ソースファイル一式 source code
02-JumpAct.zip
MITライセンスです。
JumpAct.cs
// #2 ジャンプアクション Jump Action 2017/11/21 T.Umezawa
using System;
using System.Collections.Generic;
class Unit
{
protected int mX, mY;
protected int mDX, mDY;
protected bool mGround = true;
public Unit( int x, int y, int dx, int dy )
{
mX = x;
mY = y;
mDX = dx;
mDY = dy;
}
public virtual void step()
{
mX += mDX;
int x0 = mX / 8;
int y0 = mY / 8;
int x1 = ( mX + 7 ) / 8;
int y1 = ( mY + 7 ) / 8;
if( JumpAct.sMap[ y0, x0 ] != 0 ||
JumpAct.sMap[ y0, x1 ] != 0 ||
JumpAct.sMap[ y1, x0 ] != 0 ||
JumpAct.sMap[ y1, x1 ] != 0 ){
mDX = -mDX;
mX += mDX;
}
mY += mDY;
x0 = mX / 8;
y0 = mY / 8;
x1 = ( mX + 7 ) / 8;
y1 = ( mY + 7 ) / 8;
if( !mGround && mDY < 6 ){
mDY++;
}
if( mDY < 0 && ( JumpAct.sMap[ y0, x0 ] != 0 || JumpAct.sMap[ y0, x1 ] != 0 ) ){
mDY = 1;
mY = mY / 8 * 8 + 8;
}
if( mDY > 0 && ( JumpAct.sMap[ y1, x0 ] != 0 || JumpAct.sMap[ y1, x1 ] != 0 ) ){
mDY = 0;
mY = mY / 8 * 8;
mGround = true;
}
if( mGround && JumpAct.sMap[ y0 + 1, x0 ] == 0 && JumpAct.sMap[ y0 + 1, x1 ] == 0 ){
mGround = false;
mY++;
mDY = 1;
}
}
public bool isCollision( Unit u )
{
return( Math.Abs( mX - u.mX ) < 7 && Math.Abs( mY - u.mY ) < 7 );
}
}
class Player : Unit
{
static System.Drawing.Bitmap sBM = new System.Drawing.Bitmap( "player.png" );
static System.Drawing.Rectangle sRect = new System.Drawing.Rectangle( 0, 0, 8, 8 );
public Player() : base( 0, 8 * 10, 1, 0 )
{
}
public void draw( System.Drawing.Graphics g )
{
sRect.X = ( mX & 1 ) * 8;
sRect.Y = ( mDX + 1 ) / 2 * 8;
g.DrawImage( sBM, mX, mY, sRect, System.Drawing.GraphicsUnit.Pixel );
}
public void jump()
{
if( mGround ){
mGround = false;
mDY = -7;
}
}
public override void step()
{
base.step();
if( mX == 0 || mX == 120 - 8 ){
mDX = -mDX;
}
if( mY < 0 ){
JumpAct.sGameClear = true;
}
}
}
class Enemy : Unit
{
static System.Drawing.Bitmap sBM = new System.Drawing.Bitmap( "monster.png" );
public Enemy( int x, int dx ) : base( x, 0, dx, 0 )
{
}
public void draw( System.Drawing.Graphics g )
{
g.DrawImage( sBM, mX, mY );
}
public void step( List le )
{
step();
if( mX == 0 || mX == 120 - 8 ){
if( mY < 10 * 8 ){
mDX = -mDX;
}else{
mX = JumpAct.sRnd.Next( 100 ) + 10;
mY = 0;
}
}
foreach( Enemy en in le ){
if( en == this || !isCollision( en ) ){
continue;
}
mDX = Math.Sign( mX - en.mX );
if( mDX == 0 ){
mDX = 1;
}
en.mDX = -mDX;
}
}
}
class JumpAct : MyForm
{
public static byte[,] sMap = new byte[ 12, 15 ];
public static Random sRnd = new Random();
static readonly System.Drawing.Bitmap sBM = new System.Drawing.Bitmap( "block.png" );
System.Drawing.Font mFont = new System.Drawing.Font( "MS Gothic", 4 );
int mCount;
Player mPlayer;
List mLEnemy = new List();
public static bool sGameClear, sGameOver;
protected override void OnLoad( EventArgs e )
{
base.OnLoad( e );
BackColor = System.Drawing.Color.Black;
mPlayer = new Player();
for( int i = 0; i < 5; i++ ){
mLEnemy.Add( new Enemy( i * 20 + 10, sRnd.Next( 2 ) * 2 - 1 ) );
}
for( int x = 0; x < sMap.GetLength( 1 ); x++ ){
sMap[ sMap.GetLength( 0 ) - 1, x ] = 1;
}
byte v = 1;
int n = 1;
for( int y = 2; y <= 8; y += 3 ){
for( int x = 0; x < sMap.GetLength( 1 ); x++, n-- ){
if( n == 0 ){
v = (byte)( 1 - v );
n = sRnd.Next( 2 ) + v + 1;
}
sMap[ y, x ] = v;
}
}
mTimer.Interval = 50;
mTimer.Start();
}
protected override void OnMouseDown( System.Windows.Forms.MouseEventArgs e )
{
mPlayer.jump();
base.OnMouseMove( e );
}
protected override void OnPaint( System.Windows.Forms.PaintEventArgs e )
{
System.Drawing.Graphics g = e.Graphics;
g.ScaleTransform( 8, 8 );
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
for( int y = 0; y < sMap.GetLength( 0 ); y++ ){
for( int x = 0; x < sMap.GetLength( 1 ); x++ ){
if( sMap[ y, x ] != 0 ){
g.DrawImage( sBM, x * 8, y * 8 );
}
}
}
mPlayer.draw( g );
foreach( Enemy en in mLEnemy ){
en.draw( g );
}
g.DrawString( "TIME " + mCount, mFont, mSBWhite, 0, 0 );
if( sGameClear ){
g.DrawString( "GAME CLEAR!", mFont, mSBWhite, 40, 40 );
}
if( sGameOver ){
g.DrawString( "GAME OVER", mFont, mSBWhite, 40, 40 );
}
}
protected override void onMyTimer( object sender, System.Timers.ElapsedEventArgs e )
{
if( sGameClear || sGameOver ){
return;
}
mCount++;
mPlayer.step();
foreach( Enemy en in mLEnemy ){
if( ( mCount & 1 ) == 0 ){
en.step( mLEnemy );
}
if( mPlayer.isCollision( en ) ){
sGameOver = true;
}
}
Invalidate();
}
[STAThread]
static void Main()
{
System.Windows.Forms.Application.Run( new JumpAct() );
}
}
MyForm.cs
// Form継承 2017/11/21 T.Umezawa
using System;
using System.Collections.Generic;
class MyForm : System.Windows.Forms.Form
{
protected System.Timers.Timer mTimer = new System.Timers.Timer();
protected System.Drawing.SolidBrush mSBWhite = new System.Drawing.SolidBrush( System.Drawing.Color.White );
protected override void OnLoad( EventArgs e )
{
ClientSize = new System.Drawing.Size( 960, 720 );
Left = 62; // キャプチャ都合上
Top = 20; // キャプチャ都合上
DoubleBuffered = true;
mTimer.Elapsed += new System.Timers.ElapsedEventHandler( onMyTimer );
}
protected virtual void onMyTimer( object sender, System.Timers.ElapsedEventArgs e )
{
}
}