#7 固定画面アクション3 FS Action3

ソースファイル一式 source code
07-FSAct3.zip

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


FSAct3.cs
// #6 固定画面アクション3 FS Action3 2017/11/29 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, 30 ]; public static void create() { for( int x = 0; x < sMap.GetLength( 1 ); x++ ){ sMap[ sMap.GetLength( 0 ) - 1, x ] = 1; sMap[ sMap.GetLength( 0 ) - 2, x ] = 1; } byte v = 1; int n = 1; for( int y = 5; y <= 17; y += 4 ){ for( int x = 0; 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 int getAngle4i( Unit u ) { return( Util.GetAngle4i( u.mX - mX, u.mY - mY ) ); } public bool isBlock() { return( Map.IsBlock( mX, mY ) ); } public void jump( int dy ) { if( mJump == 0 ){ mJump = 1; } mDY = dy; } public virtual void step() { if( mJump > 0 ){ mJump++; } mX += mDX; if( isBlock() ){ mDX = -mDX; mX += mDX; } mY += mDY; if( mJump > 0 && mDY < 6 * 256 / DOT ){ // 重力 mDY += 8; } if( mDY < 0 && isBlock() ){ // 上昇中 if( !Map.IsBlock( mX + 16, mY ) ){ mX += 16; }else if( !Map.IsBlock( mX - 16, mY ) ){ mX -= 16; }else{ // 天井にぶつかる mDY = 0; mY = (int)( ( (int)( mY / 256.0f - 0.5f ) + 1.5f ) * 256 ); } } if( mDY > 0 && isBlock() ){ // 下降中 mDY = 0; // 着地 mY = (int)( ( (int)( mY / 256.0f - 0.5f ) + 0.5f ) * 256 ); mJump = 0; } if( mJump == 0 && !Map.IsBlock( mX, mY + 256 / DOT ) ){ // 地面から落ちる mJump = 1; mY += 256 / DOT; mDY = 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" ), new System.Drawing.Bitmap( "player2.png" ) }; static System.Drawing.Rectangle sRect = new System.Drawing.Rectangle( 0, 0, 8, 8 ); public int mType; public int mBtnA; public int mBtnB; public int mBtnL; public int mBtnR; int mAngle; public Player( int type ) : base( 128, 20 * 256 + 128, 0, 0 ) { mType = type; } public void draw( System.Drawing.Graphics g ) { sRect.X = ( (int)( mX * 4 / 256 ) & 1 ) * DOT; sRect.Y = mAngle * DOT; if( mJump != 0 ){ sRect.X = 0; } g.DrawImage( sBM[ mType ], mX * DOT / 256.0f - DTH, mY * DOT / 256.0f - DTH, sRect, System.Drawing.GraphicsUnit.Pixel ); } public void jump() { if( mJump == 0 ){ // 接地中の場合 if( Math.Abs( mDX ) > 32 ){ jump( -88 ); }else{ jump( -80 ); } }else if( mDY < 0 ){ // 上昇中の場合 mDY -= 5; } } public override void step() { if( mBtnA > 0 ){ jump(); } int max = 32; if( mBtnB > 0 ){ max = 56; } if( mBtnL > 0 ){ mAngle = 0; mDX -= 2; if( mDX < -max ){ mDX = -max; } }else if( mBtnR > 0 ){ mAngle = 1; mDX += 2; if( mDX > max ){ mDX = max; } }else if( mDX != 0 ){ mDX -= Math.Sign( mDX ) * 4; } base.step(); if( mX <= 128 || mX >= Map.sMap.GetLength( 1 ) * 256 - 128 ){ mDX = 0; } if( Map.sMap[ (int)( mY / 256 ), (int)( mX / 256 ) ] == 2 ){ FSAct3.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 mState; public int Speed{ get{ return( 8 * ( mType + 1 ) * ( mState * 3 + 1 ) ); } } public Enemy( int type ) : base( FSAct3.sRnd.Next( Map.sMap.GetLength( 1 ) - 2 ) * 256 + 128, 128, ( FSAct3.sRnd.Next( 2 ) * 16 - 8 ) * ( type + 1 ), 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; } sRectS.X = mState * DOT; 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( mX <= 128 || mX >= Map.sMap.GetLength( 1 ) * 256 - 128 ){ mDX = Math.Sign( Map.sMap.GetLength( 1 ) * 128 - mX ) * Speed; } foreach( Enemy en in le ){ if( en == this || !isCollision( en ) ){ continue; } bool km = ( mState == 1 && mDX != 0 ); bool ke = ( en.mState == 1 && en.mDX != 0 ); if( km ) en.kill(); if( ke ) kill(); if( km || ke ){ continue; } mDX = Math.Sign( mX - en.mX ) * Speed; if( mDX == 0 ){ mDX = Speed; } en.mDX = -mDX; } } } class FSAct3 : 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( "固定画面アクション2 FS Action2", mFont, mSBWhite, 60, 30 ); g.DrawString( "PRESS ANY KEY", mFont, mSBWhite, 90, 90 ); return; } Map.draw( g ); foreach( Player pl in mLPlayer ){ pl.draw( g ); } foreach( Enemy en in Enemy.sList ){ en.draw( g ); } 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( mKey[ (int)System.Windows.Forms.Keys.R ] == 1 ) input( 1, true ); if( mKey[ (int)System.Windows.Forms.Keys.Z ] > 0 ) input( 1, false ); if( mKey[ (int)System.Windows.Forms.Keys.Z ] == 0 ) release( 1 ); Player p = getPlayer( 1 ); if( p != null ){ p.mBtnB = mKey[ (int)System.Windows.Forms.Keys.X ]; p.mBtnL = mKey[ (int)System.Windows.Forms.Keys.Left ]; p.mBtnR = mKey[ (int)System.Windows.Forms.Keys.Right ]; } 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 ) ){ // 敵に接触 continue; } int an = pl.getAngle4i( en ); if( en.mType == 1 && en.mState == 1 ){ if( en.mDX == 0 ){ en.mDX = Math.Sign( en.mX - pl.mX ); en.mDX *= en.Speed; if( pl.mJump > 0 ){ pl.jump( -64 ); } }else if( an == 1 ){ en.mDX = 0; pl.jump( -64 ); } continue; } if( an != 1 ){ // 敵にやられる sGameOver = true; continue; } pl.jump( -64 ); if( en.mType == 0 ){ // スライムだった場合 en.kill(); continue; } if( en.mState == 0 ){ en.mState = 1; en.mDX = 0; continue; } en.mDX = Math.Sign( en.mX - pl.mX ); if( en.mDX == 0 ){ en.mDX = 1; } en.mDX *= en.Speed; } } 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( type ) ); }else if( sGameClear ){ mStage++; start(); mLPlayer.Add( new Player( type ) ); }else if( res ){ mStage = 1; start(); mLPlayer.Add( new Player( type ) ); }else if( mLPlayer[ 0 ].mType != type ){ if( mLPlayer.Count == 1 ){ mLPlayer.Add( new Player( type ) ); }else{ mLPlayer[ 1 ].mBtnA = 1; } }else{ mLPlayer[ 0 ].mBtnA = 1; } } Player getPlayer( int type ) { foreach( Player p in mLPlayer ){ if( p.mType == type ){ return( p ); } } return( null ); } void release( int type ) { Player p = getPlayer( type ); if( p != null ){ p.mBtnA = 0; } } void start() { mScene = 1; sGameClear = false; sGameOver = false; mCount = 0; mLPlayer.Clear(); Enemy.sList = new List(); for( int i = 0; i < mStage * 2; 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 FSAct3() ); } }


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 int[] mKey = new int[ 0x100 ]; public int[] mMouseB = new int[ 0x20 ]; public int MouseLeft{ get{ return( mMouseB[ (int)Math.Log( (int)System.Windows.Forms.MouseButtons.Left , 2 ) ] ); } } public int MouseMiddle{ get{ return( mMouseB[ (int)Math.Log( (int)System.Windows.Forms.MouseButtons.Middle, 2 ) ] ); } } public int MouseRight{ get{ return( mMouseB[ (int)Math.Log( (int)System.Windows.Forms.MouseButtons.Right , 2 ) ] ); } } protected override void OnKeyDown( System.Windows.Forms.KeyEventArgs e ) { mKey[ (int)e.KeyCode ] = 1; base.OnKeyDown( e ); } protected override void OnKeyUp( System.Windows.Forms.KeyEventArgs e ) { mKey[ (int)e.KeyCode ] = 0; base.OnKeyUp( e ); } protected override void OnMouseDown( System.Windows.Forms.MouseEventArgs e ) { mMouseB[ (int)Math.Log( (int)e.Button, 2 ) ] = 1; base.OnMouseDown( e ); } protected override void OnMouseUp( System.Windows.Forms.MouseEventArgs e ) { mMouseB[ (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 < mKey.Length; i++ ){ if( mKey[ i ] > 0 ){ mKey[ i ]++; } } for( int i = 0; i < mMouseB.Length; i++ ){ if( mMouseB[ i ] > 0 ){ mMouseB[ i ]++; } } } }


[戻る]
管理人:T.Umezawa