ソースファイル一式 source code
08-LDAct.zip
MITライセンスです。
This software/source is licensed under the MIT License, see LICENSE.txt.
LDActn.cs
//	#8 見下ろし型アクション LD Action 2017/12/01 T.Umezawa
using System;
using System.Collections.Generic;
class Util
{
	public static int GetAngle4i( double dx, double dy )
	{
		return( (int)( ( GetAngle360( dx, dy ) + 45 ) / 90 ) & 0x03 );
	}
	public static double GetAngle360( double dx, double dy )
	{
		double	r = Math.Atan2( dy, dx ) * 180 / Math.PI;
		if( r < 0 ){
			r += 360;
		}
		return( r );
	}
}
class Map
{
	static System.Drawing.Bitmap[]	sBM = {
		new System.Drawing.Bitmap( "block.png" ),
		new System.Drawing.Bitmap( "flag.png" ),
	};
	public static byte[,]		sMap = new byte[ 23, 31 ];
	public static void create()
	{
		Array.Clear( sMap, 0, sMap.Length );
		for( int y = 0; y < sMap.GetLength( 0 ); y++ ){
			sMap[ y, 0 ] = 1;
			sMap[ y, sMap.GetLength( 1 ) - 1 ] = 1;
		}
		for( int x = 0; x < sMap.GetLength( 1 ); x++ ){
			sMap[ 0, x ] = 1;
			sMap[ sMap.GetLength( 0 ) - 1, x ] = 1;
		}
		for( int y = 2; y < sMap.GetLength( 0 ) - 2; y += 2 ){
			for( int x = 2; x < sMap.GetLength( 1 ) - 2; x += 2 ){
				sMap[ y, x ] = 1;
			}
		}
		sMap[ 1, 29 ] = 2;
	}
	public static void draw( System.Drawing.Graphics g )
	{
		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[ sMap[ y, x ] - 1 ], x * 8, y * 8 );
				}
			}
		}
	}
	public static bool IsArea( int x, int y )
	{
		return( x >= 0 && x < sMap.GetLength( 1 ) &&
		        y >= 0 && y < sMap.GetLength( 0 ) );
	}
	public static bool IsBlock( int x, int y )
	{
		x -= 128;
		y -= 128;
		int		x0 = x / 256;
		int		y0 = y / 256;
		int		x1 = ( x + 255 ) / 256;
		int		y1 = ( y + 255 ) / 256;
		return( IsBlockM( x0, y0 ) ||
		        IsBlockM( x1, y0 ) ||
		        IsBlockM( x0, y1 ) ||
		        IsBlockM( x1, y1 ) );
	}
	public static bool IsBlockM( int x, int y )
	{
		return( !IsArea( x, y ) || sMap[ y, x ] == 1 );
	}
}
class Unit
{
	public static readonly int		DOT = 8;
	public static readonly int		DTH = DOT / 2;
	public int		mX, mY;
	public int		mDX, mDY;
	public int		mJump;
	public Unit( int x, int y, int dx, int dy )
	{
		mX = x;
		mY = y;
		mDX = dx;
		mDY = dy;
	}
	public bool isBlock()
	{
		return( Map.IsBlock( mX, mY ) );
	}
	public virtual void step()
	{
		if( mJump > 0 ){
			mJump++;
		}
		int		mx = Math.Sign( mDX );
		mX += mx * 16;
		mDX -= mx;
		if( isBlock() ){
			mDX = 0;
			mX -= mx * 16;
		}
		int		my = Math.Sign( mDY );
		mY += my * 16;
		mDY -= my;
		if( isBlock() ){
			mDY = 0;
			mY -= my * 16;
		}
	}
	public bool isCollision( Unit u )
	{
		return( Math.Abs( mX - u.mX ) < 6.0f * 256 / DOT && Math.Abs( mY - u.mY ) < 6.0f * 256 / DOT );
	}
}
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 int		mBtnA;
	public int		mBtnB;
	int				mAngle;
	public Player() : base( 256 + 128, 21 * 256 + 128, 0, 0 )
	{
	}
	public void draw( System.Drawing.Graphics g )
	{
		sRect.X = ( (int)( ( mX + mY ) * 4 / 256 ) & 1 ) * DOT;
		sRect.Y = mAngle * DOT;
		if( mJump != 0 ){
			sRect.X = 0;
		}
		g.DrawImage( sBM[ 0 ], mX * DOT / 256.0f  - DTH, mY * DOT / 256.0f - DTH, sRect, System.Drawing.GraphicsUnit.Pixel );
	}
	public override void step()
	{
		if( mDX == 0 && mDY == 0 ){
			if( MyForm.sKey[ (int)System.Windows.Forms.Keys.Down  ] > 0 ){	mAngle = 0;	mDY = 16;	}else
			if( MyForm.sKey[ (int)System.Windows.Forms.Keys.Left  ] > 0 ){	mAngle = 1;	mDX = -16;	}else
			if( MyForm.sKey[ (int)System.Windows.Forms.Keys.Right ] > 0 ){	mAngle = 2;	mDX = 16;	}else
			if( MyForm.sKey[ (int)System.Windows.Forms.Keys.Up    ] > 0 ){	mAngle = 3;	mDY = -16;	}
		}
		base.step();
		if( Map.sMap[ (int)( mY / 256 ), (int)( mX / 256 ) ] == 2 ){
			LDAct.sGameClear = true;
		}
	}
}
class Enemy : Unit
{
	public static List			sList;
	static System.Drawing.RectangleF	sRectD = new System.Drawing.RectangleF( 0, 0, 8, 8 );
	static System.Drawing.RectangleF	sRectS = new System.Drawing.RectangleF( 0, 0, 8, 8 );
	static System.Drawing.Bitmap[]	sBM = {
		new System.Drawing.Bitmap( "monster.png" ),
		new System.Drawing.Bitmap( "monster2.png" ),
	};
	public int		mType;
	public int Speed{	get{	return( 8 * ( mType + 1 ) );	}	}
	public Enemy( int type ) : base( LDAct.sRnd.Next( Map.sMap.GetLength( 1 ) - 16 ) * 256 + 256 * 15 + 128, LDAct.sRnd.Next( 4 ) * 512 + 256 + 128, 0, 0 )
	{
		mType = type;
	}
	public void draw( System.Drawing.Graphics g )
	{
		sRectD.Y = mY * DOT / 256.0f - DTH;
		if( mDX < 0 ){
			sRectD.X = mX * DOT / 256.0f - DTH;
			sRectD.Width = 8;
		}else{
			sRectD.X = mX * DOT / 256.0f + DTH;
			sRectD.Width = -8;
		}
		g.DrawImage( sBM[ mType ], sRectD, sRectS, System.Drawing.GraphicsUnit.Pixel );
	}
	public void kill()
	{
		sList.Add( new Enemy( mType ) );
		sList.Remove( this );
	}
	public void step( List le )
	{
		step();
		if( mDX == 0 && mDY == 0 ){
			mDX = LDAct.sRnd.Next( 3 ) * 16 - 16;
			mDY = LDAct.sRnd.Next( 3 ) * 16 - 16;
		}
		foreach( Enemy en in le ){
			if( en == this || !isCollision( en ) ){
				continue;
			}
			mDX = -mDX;
			mDY = -mDY;
			en.mDX = -en.mDX;
			en.mDY = -en.mDY;
		}
	}
}
class LDAct : MyForm
{
	public static Random		sRnd = new Random();
	System.Drawing.Font			mFont = new System.Drawing.Font( "MS Gothic", 5 );
	int							mCount;
	List				mLPlayer = new List();
	public static bool			sGameClear, sGameOver;
	int							mStage = 1;
	int							mScene;
	protected override void OnLoad( EventArgs e )
	{
		base.OnLoad( e );
		mTimer.Interval = 33;
		mTimer.Start();
	}
	protected override void onMyPaint( System.Drawing.Graphics g )
	{
		if( mScene == 0 ){
			g.DrawString( "見下ろし型アクション LD Action", mFont, mSBWhite, 60, 30 );
			g.DrawString( "PRESS ANY KEY", mFont, mSBWhite, 90, 90 );
			return;
		}
		g.TranslateTransform( -4, -2 );
		Map.draw( g );
		foreach( Player pl in mLPlayer ){
			pl.draw( g );
		}
		foreach( Enemy en in Enemy.sList ){
			en.draw( g );
		}
		g.TranslateTransform( 4, 2 );
		g.DrawString( "TIME " + mCount, mFont, mSBWhite, 0, 0 );
		g.DrawString( "STAGE " + mStage, mFont, mSBWhite, 40, 0 );
		if( sGameClear ){
			g.DrawString( "STAGE CLEAR!", mFont, mSBWhite, 90, 90 );
		}
		if( sGameOver ){
			g.DrawString( "GAME OVER", mFont, mSBWhite, 90, 90 );
		}
	}
	protected override void onMyTimer( object sender, System.Timers.ElapsedEventArgs e )
	{
		if( sKey[ (int)System.Windows.Forms.Keys.R ] == 1 )	input( 1, true  );
		if( sKey[ (int)System.Windows.Forms.Keys.Z ] >  0 )	input( 1, false );
		if( mLPlayer[ 0 ] != null ){
			mLPlayer[ 0 ].mBtnA = sKey[ (int)System.Windows.Forms.Keys.Z     ];
			mLPlayer[ 0 ].mBtnB = sKey[ (int)System.Windows.Forms.Keys.X     ];
		}
		if( sGameClear || sGameOver ){
			return;
		}
		mCount++;
		foreach( Player pl in mLPlayer ){
			pl.step();
			for( int i = Enemy.sList.Count - 1; i >= 0; i-- ){
				Enemy	en = Enemy.sList[ i ];
				if( pl.isCollision( en ) ){	//	敵に接触
					sGameOver = true;
				}
			}
		}
		for( int i = Enemy.sList.Count - 1; i >= 0; i-- ){
			Enemy	en = Enemy.sList[ i ];
			en.step( Enemy.sList );
		}
		base.onMyTimer( sender, e );
		Invalidate();
	}
	void input( int type, bool res )
	{
		if( mScene == 0 ){
			mStage = 1;
			start();
			mLPlayer.Add( new Player() );
		}else if( sGameClear ){
			mStage++;
			start();
			mLPlayer.Add( new Player() );
		}else if( res ){
			mStage = 1;
			start();
			mLPlayer.Add( new Player() );
		}
	}
	void start()
	{
		mScene = 1;
		sGameClear = false;
		sGameOver = false;
		mCount = 0;
		mLPlayer.Clear();
		Enemy.sList = new List();
		for( int i = 0; i < mStage * 4; i++ ){
			Enemy.sList.Add( new Enemy( 0 ) );
			Enemy.sList.Add( new Enemy( 1 ) );
		}
		Map.create();
	}
	[STAThread]
	static void Main()
	{
		System.Windows.Forms.Application.Run( new LDAct() );
	}
}
     
MyForm.cs
//	Form継承 2017/11/27 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 );
	public static int[]		sKey = new int[ 0x100 ];
	public static int[]		sMouseB = new int[ 0x20 ];
	public static int MouseLeft{	get{	return( sMouseB[ (int)Math.Log( (int)System.Windows.Forms.MouseButtons.Left  , 2 ) ] );	}	}
	public static int MouseMiddle{	get{	return( sMouseB[ (int)Math.Log( (int)System.Windows.Forms.MouseButtons.Middle, 2 ) ] );	}	}
	public static int MouseRight{	get{	return( sMouseB[ (int)Math.Log( (int)System.Windows.Forms.MouseButtons.Right , 2 ) ] );	}	}
	protected override void OnKeyDown( System.Windows.Forms.KeyEventArgs e )
	{
		sKey[ (int)e.KeyCode ] = 1;
		base.OnKeyDown( e );
	}
	protected override void OnKeyUp( System.Windows.Forms.KeyEventArgs e )
	{
		sKey[ (int)e.KeyCode ] = 0;
		base.OnKeyUp( e );
	}
	protected override void OnMouseDown( System.Windows.Forms.MouseEventArgs e )
	{
		sMouseB[ (int)Math.Log( (int)e.Button, 2 ) ] = 1;
		base.OnMouseDown( e );
	}
	protected override void OnMouseUp( System.Windows.Forms.MouseEventArgs e )
	{
		sMouseB[ (int)Math.Log( (int)e.Button, 2 ) ] = 0;
		base.OnMouseUp( e );
	}
	protected override void OnLoad( EventArgs e )
	{
		ClientSize = new System.Drawing.Size( 960, 720 );
//		Left = 396;	//	キャプチャ都合上
//		Top = 20;	//	キャプチャ都合上
		DoubleBuffered = true;
		BackColor = System.Drawing.Color.FromArgb( 0x55, 0x88, 0xff );
		mTimer.Elapsed += new System.Timers.ElapsedEventHandler( onMyTimer );
	}
	protected override void OnPaint( System.Windows.Forms.PaintEventArgs e )
	{
		base.OnPaint( e );
		System.Drawing.Graphics	g = e.Graphics;
		g.ScaleTransform( 4, 4 );
		g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
		g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
		onMyPaint( g );
	}
	protected virtual void onMyPaint( System.Drawing.Graphics g )
	{
	}
	protected virtual void onMyTimer( object sender, System.Timers.ElapsedEventArgs e )
	{
		for( int i = 0; i < sKey.Length; i++ ){
			if( sKey[ i ] > 0 ){
				sKey[ i ]++;
			}
		}
		for( int i = 0; i < sMouseB.Length; i++ ){
			if( sMouseB[ i ] > 0 ){
				sMouseB[ i ]++;
			}
		}
	}
}