#10 見下ろし型アクション3 LD Action3

ソースファイル一式 source code
10-LDAct3.zip

MITライセンスです。
This software/source is licensed under the MIT License, see LICENSE.txt.


LDAct3.cs
// #10 見下ろし型アクション3 LD Action3 2017/12/03 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.SolidBrush sSBFloor = new System.Drawing.SolidBrush( System.Drawing.Color.FromArgb( 0x22, 0x00, 0x00 ) ); static System.Drawing.Bitmap[] sBM = { new System.Drawing.Bitmap( "block.png" ), new System.Drawing.Bitmap( "flag.png" ), }; public static byte[,] sMap = new byte[ 21, 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; } } // 迷路作成 for( int y = 2; y < sMap.GetLength( 0 ) - 2; y += 2 ){ for( int x = 2; x < sMap.GetLength( 1 ) - 2; x += 2 ){ if( isWall( x, y ) ){ continue; } int a = LDAct3.sRnd.Next( 4 ); if( a == 0 ) sMap[ y - 1, x ] = 1; if( a == 1 ) sMap[ y + 1, x ] = 1; if( a == 2 ) sMap[ y, x - 1 ] = 1; if( a == 3 ) sMap[ y, x + 1 ] = 1; } } sMap[ 3, 27 ] = 2; } static bool isWall( int x, int y ) { return( sMap[ y - 1, x ] != 0 || sMap[ y + 1, x ] != 0 || sMap[ y, x - 1 ] != 0 || sMap[ y, x + 1 ] != 0 ); } 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.FillRectangle( sSBFloor, x * 8, y * 8, 7, 7 ); }else{ 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 { public static List sList = new List(); static System.Drawing.Font sFont = new System.Drawing.Font( "MS Gothic", 5 ); static System.Drawing.SolidBrush sSBWhite = new System.Drawing.SolidBrush( System.Drawing.Color.White ); static System.Drawing.Bitmap[] sBM = { new System.Drawing.Bitmap( "player.png" ), }; static System.Drawing.Rectangle sRect = new System.Drawing.Rectangle( 2, 2, 8, 8 ); public int mBtnA; public int mBtnB; int mAngle; public int mHP = 30; public int mMHP = 30; public Player() : base( 256 * 3 + 128, ( Map.sMap.GetLength( 0 ) - 4 ) * 256 + 128, 0, 0 ) { } public void draw( System.Drawing.Graphics g ) { sRect.X = ( (int)( ( mX + mY ) * 4 / 256 ) & 1 ) * ( DOT + DOT / 2 ) + 2; sRect.Y = mAngle * ( DOT + DOT / 2 ) + 2; 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 ); g.DrawString( "HP " + mHP, sFont, sSBWhite, 10, 170 ); } public void start() { mHP = mMHP; mX = 256 * 3 + 128; mY = ( Map.sMap.GetLength( 0 ) - 4 ) * 256 + 128; mDX = 0; mDY = 0; } 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; } } if( mHP < mMHP && ( ( LDAct3.sCount & 0x3f ) == 0 ) ){ mHP++; } base.step(); if( Map.sMap[ (int)( mY / 256 ), (int)( mX / 256 ) ] == 2 ){ LDAct3.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 mHP = 20; public int Speed{ get{ return( 8 * ( mType + 1 ) ); } } public Enemy( int type ) : base( LDAct3.sRnd.Next( Map.sMap.GetLength( 1 ) - 16 ) * 512 + 256 * 15 + 128, LDAct3.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; } if( mDY != 0 ){ sRectS.Y = ( 3 - Math.Sign( mDY ) ) / 2 * DOT; }else{ sRectS.Y = 0; } 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 = LDAct3.sRnd.Next( 3 ) * 16 - 16; mDY = LDAct3.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 LDAct3 : MyForm { public static Random sRnd = new Random(); System.Drawing.Font mFont = new System.Drawing.Font( "MS Gothic", 5 ); public static int sCount; 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( "見下ろし型アクション3 LD Action3", mFont, mSBWhite, 60, 30 ); g.DrawString( "PRESS ANY KEY", mFont, mSBWhite, 90, 90 ); return; } g.TranslateTransform( -4, 0 ); Map.draw( g ); foreach( Player pl in Player.sList ){ pl.draw( g ); } foreach( Enemy en in Enemy.sList ){ en.draw( g ); } g.TranslateTransform( 4, 0 ); g.DrawString( "TIME " + sCount, mFont, mSBWhite, 200, 170 ); g.DrawString( "STAGE " + mStage, mFont, mSBWhite, 170, 170 ); 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( Player.sList.Count > 0 ){ Player.sList[ 0 ].mBtnA = sKey[ (int)System.Windows.Forms.Keys.Z ]; Player.sList[ 0 ].mBtnB = sKey[ (int)System.Windows.Forms.Keys.X ]; } if( sGameClear || sGameOver ){ return; } sCount++; for( int i = Player.sList.Count - 1; i >= 0; i-- ){ Player pl = Player.sList[ i ]; pl.step(); for( int j = Enemy.sList.Count - 1; j >= 0; j-- ){ Enemy en = Enemy.sList[ j ]; if( pl.isCollision( en ) ){ // 敵に接触 pl.mHP--; en.mHP--; if( pl.mHP <= 0 ){ sGameOver = true; } if( en.mHP <= 0 ){ Enemy.sList.RemoveAt( j ); pl.mMHP++; } } } } 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(); Player.sList.Add( new Player() ); }else if( sGameClear ){ mStage++; start(); Player.sList[ 0 ].start(); }else if( res ){ mStage = 1; start(); Player.sList.Clear(); Player.sList.Add( new Player() ); } } void start() { mScene = 1; sGameClear = false; sGameOver = false; sCount = 0; 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 LDAct3() ); } }


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 ); BackColor = System.Drawing.Color.Black; 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 ]++; } } } }


[戻る]
管理人:T.Umezawa