"use strict";
var Resource =
{
Tilemap : [
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
[ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 ],
[ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 ],
],
}
let WIDTH = 23;
let HEIGHT = 23;
let TILE = 8;
let CHRSIZE = 32;
var DL =
{
SCALE : 3,
TILE : 8,
mTile8 : [],
mTile32 : [],
DrawString : function( x, y, s, color )
{
TUGames.GX.DrawString( s, x, y, 0, color ); // 座標XYZへ、ABGR形式で指定した色で文字列を描画
},
DrawTexture : function( x0, y0, x1, y1, gh )
{
TUGames.GX.DrawTexture( gh, x0, y0, 0, x1 - x0, y1 - y0 );
},
DrawTextureR : function( pos, atr, gh )
{
let h = atr & 1;
let v = ( atr & 2 ) >> 1;
this.DrawTexture(
pos.mX + pos.mWidth * h , pos.mY + pos.mHeight * v ,
pos.mX + pos.mWidth * (h^1), pos.mY + pos.mHeight * (v^1),
gh );
},
DrawTilemap : function()
{
if( DL.sPriTilemap == null ){
DL.sPriTilemap = TUGames.Primitive.CreateMap( TUGames.GU.Format.T2F_V3F, WIDTH, HEIGHT, TILE, TILE, DL.mTex8, Resource.Tilemap );
}
DL.sPriTilemap.draw();
},
FillRect : function( x1, y1, x2, y2, color )
{
TUGames.GX.FillRect( x1, y1, 0, x2 - x1, y2 - y1, color );
},
}
class Rectangle
{
constructor( x, y, width, height )
{
this.mX = x;
this.mY = y;
this.mWidth = width;
this.mHeight = height;
}
intersectsWith( rect )
{
//console.log( "this.mX=" + this.mX + " this.mY=" + this.mY + " this.mWidth=" + this.mWidth + " this.mHeight=" + this.mHeight );
//console.log( "rect.mX=" + rect.mX + " rect.mY=" + rect.mY + " rect.mWidth=" + rect.mWidth + " rect.mHeight=" + rect.mHeight );
let sw = this.mWidth / 2;
let sh = this.mHeight / 2;
let rw = rect.mWidth / 2;
let rh = rect.mHeight / 2;
return( Math.abs( ( this.mX + sw ) - ( rect.mX + rw ) ) < ( sw + rw ) &&
Math.abs( ( this.mY + sh ) - ( rect.mY + rh ) ) < ( sh + rh ) );
}
}
class Size
{
constructor( width, height )
{
this.mWidth = width;
this.mHeight = height;
}
}
class Sprite
{
constructor( gh, pos )
{
this.mGH = gh;
this.mPos = pos;
this.mAtr = 0;
}
add( width, height )
{
this.mPos.mX += width;
this.mPos.mY += height;
}
draw( idx )
{
DL.DrawTextureR( this.mPos, this.mAtr, this.mGH[ idx ] );
}
intersectsWith( rect )
{
return( this.mPos.intersectsWith( rect ) );
}
}
class Character extends Sprite
{
constructor( gh, pos, col )
{
//console.log( "Character#constructor pos=" + pos );
super( gh, pos );
this.mCol = col;
this.mColIdx = 0;
this.addCol( pos.mX, pos.mY );
}
add( dx, dy )
{
super.add( dx, dy );
this.addCol( dx, dy );
}
addCol( dx, dy )
{
for( let i = 0; i < this.mCol.length; i++ ){
this.mCol[ i ].mX += dx;
this.mCol[ i ].mY += dy;
}
}
collision( c )
{
//console.log( "collision this.mCol[ this.mColIdx ]=" + this.mCol[ this.mColIdx ] + " c.mCol[ c.mColIdx ]=" + c.mCol[ c.mColIdx ] );
return( this.mCol[ this.mColIdx ].intersectsWith( c.mCol[ c.mColIdx ] ) );
}
}
let mGameOver = false;
let mScore = 0;
let mHiScore = 0;
let mPlayer = [];
let mEnemy = [];
let mFire = [];
let mScreen = new Rectangle( 0, 0, WIDTH * TILE, ( HEIGHT - 2 ) * TILE );
class Enemy extends Character
{
constructor( gh, pos, col, vec )
{
//console.log( "Enemy#constructor pos=" + pos );
super( gh, pos, col );
this.mVec = vec;
}
draw()
{
super.draw( ( this.mPos.mX + this.mPos.mY ) >> 2 & 1 );
}
move()
{
super.add( this.mVec.mWidth, this.mVec.mHeight );
}
}
class Fire extends Character
{
constructor( gh, pos, col, vec )
{
//console.log( "Fire#constructor pos.mX=" + pos.mX + " pos.mY=" + pos.mY );
super( gh, pos, col );
this.mVec = vec;
}
draw()
{
//console.log( "Fire#draw " + this.mPos.mX + " " + this.mPos.mY );
super.draw( ( this.mPos.mX + this.mPos.mY ) >> 2 & 1 );
}
move()
{
super.add( this.mVec.mWidth, this.mVec.mHeight );
}
}
class Player extends Character
{
constructor( gh, pos, col )
{
//console.log( "Player#constructor pos=" + pos );
super( gh, pos, col );
this.mCrou = false;
this.mDX = 0;
this.mDY = 0;
this.mHP = 112;
this.mWait = 0;
}
get KeyStateLeft(){ return( Math.max( TUGames.PF.GetKey( 37 ), TUGames.PF.GetKey( 65 ) ) ); }
get KeyStateUp(){ return( Math.max( TUGames.PF.GetKey( 38 ), TUGames.PF.GetKey( 87 ) ) ); }
get KeyStateRight(){ return( Math.max( TUGames.PF.GetKey( 39 ), TUGames.PF.GetKey( 68 ) ) ); }
get KeyStateDown(){ return( Math.max( TUGames.PF.GetKey( 40 ), TUGames.PF.GetKey( 83 ) ) ); }
get KeyStateB(){ return( Math.max( TUGames.PF.GetKey( 78 ), TUGames.PF.GetKey( 88 ) ) ); }
damage()
{
this.mHP -= 2;
return( this.mHP <= 0 );
}
diffGround()
{
return( 20 * TILE - this.mPos.mHeight - this.mPos.mY );
}
draw()
{
if( this.mCrou ){
super.draw( 2 );
}else{
super.draw( this.mPos.mX >> 3 & 1 );
}
DL.FillRect( 16, 32, 128, 48, 0xff0000ff );
DL.FillRect( 128 - this.mHP, 32, 128, 48, 0xff00ff00 );
}
update()
{
if( this.mWait > 0 ){
this.mWait--;
return;
}
let d = this.diffGround();
this.mCrou = this.KeyStateDown > 0 && d == 0;
if( this.mCrou ){
this.mColIdx = 1;
}else{
this.mColIdx = 0;
}
if( d == 0 ){
if( this.KeyStateB == 1 && this.mWait == 0 ){
this.mWait = 30;
mFire.push( new Fire( [ DL.mTile8[ 4 ], DL.mTile8[ 5 ] ],
new Rectangle( this.mPos.mX + 20 - this.mAtr * 16, this.mPos.mY + this.mColIdx * 12 + 8, TILE, TILE ),
[ new Rectangle( 0, 0, 8, 8 ) ],
new Size( 1 - ( this.mAtr << 1 ), 0 ) ) );
}
}
if( this.mCrou ){
return;
}
if( d == 0 ){
if( this.KeyStateLeft > 0 ){
this.mDX = -1;
this.mAtr = 1;
}else if( this.KeyStateRight > 0 && this.mPos.mX + this.mPos.mWidth < WIDTH * TILE ){
this.mDX = 1;
this.mAtr = 0;
}else{
this.mDX = 0;
}
}
if( this.mDX == -1 && this.mPos.mX > 0 ){
this.add( -1, 0 );
}
if( this.mDX == 1 && this.mPos.mX + this.mPos.mWidth < WIDTH * TILE ){
this.add( 1, 0 );
}
if( d > 0 ){
this.mDY++;
}
if( this.KeyStateUp > 0 && this.diffGround() <= 0 ){
this.mDY = -24;
}
this.add( 0, this.mDY >> 3 );
d = this.diffGround();
if( d <= 0 ){
this.mDY = 0;
this.add( 0, d );
}
}
}
function AddEnemy( type )
{
let x, y, dx, dy;
if( type == 0 ){
x = WIDTH * TILE - 1;
y = Rnd( TILE * 5 ) + TILE * 14;
dx = -Rnd( 2 ) - 1;
dy = 0;
}else if( type == 1 ){
x = -7;
y = Rnd( TILE * 5 ) + TILE * 14;
dx = Rnd( 2 ) + 1;
dy = 0;
}else{
x = Rnd( WIDTH * TILE );
y = -7;
dx = Rnd( 3 ) - 1;
dy = Rnd( 2 ) + 1;
}
mEnemy.push( new Enemy( [ DL.mTile8[ 2 ], DL.mTile8[ 3 ] ],
new Rectangle( x, y, TILE, TILE ),
[ new Rectangle( 2, 1, 4, 6 ) ],
new Size( dx, dy ) ) );
}
function Rnd( m )
{
return( Math.floor( Math.random() * m ) );
}
function UpdateFrame()
{
if( mGameOver ){
if( TUGames.PF.GetKey( 13 ) <= 0 ){
return;
}
Start();
}
mHiScore = Math.max( mHiScore, ++mScore );
// if( mEnemy.length == 0 || Rnd( 200000 / ( mScore + 1000 ) ) == 0 ){
if( mEnemy.length == 0 || Rnd( 5000 / ( mScore + 1000 ) ) == 0 ){
AddEnemy( Rnd( mEnemy.length ) );
}
mPlayer[ 0 ].update();
for( let i = mEnemy.length - 1; i >= 0; i-- ){
let e = mEnemy[ i ];
e.move();
if( !e.intersectsWith( mScreen ) ){
mEnemy.splice( i, 1 );
}
if( mPlayer[ 0 ].collision( e ) ){
// mGameOver = mPlayer[ 0 ].damage();
}
}
for( let i = mFire.length - 1; i >= 0; i-- ){
let f = mFire[ i ];
f.move();
if( !f.intersectsWith( mScreen ) ){
mFire.splice( i, 1 );
continue;
}
for( let j = mEnemy.length - 1; j >= 0; j-- ){
if( f.collision( mEnemy[ j ] ) ){
mFire.splice( i, 1 );
mEnemy.splice( j, 1 );
break;
}
}
}
}
function Start()
{
mGameOver = false;
mScore = 0;
mPlayer = [];
mPlayer.push( new Player( [ DL.mTile32[ 0 ], DL.mTile32[ 1 ], DL.mTile32[ 2 ] ],
new Rectangle( WIDTH / 2 * TILE, 20 * TILE - CHRSIZE, CHRSIZE, CHRSIZE ),
[ new Rectangle( 13, 5, 6, 26 ), new Rectangle( 13, 18, 6, 13 ) ] ) );
mEnemy = [];
mFire = [];
TUGames.PF.StartLoop( 60, UpdateFrame, Draw ); // fpsを指定してループを開始し、更新処理と描画処理を登録
}
function Draw()
{
TUGames.GX.Clear(); // 設定された背景色で画面初期化
DL.DrawTilemap();
let el = mEnemy.length;
DL.sPri8.setCount( el );
for( let i = 0; i < el; i++ ){
let e = mEnemy[ i ];
let p = e.mPos;
let u = ( ( p.mX + p.mY ) >> 2 & 1 ) / 2;
DL.sPri8.setTexCoord( i, u, 0.25, 0.5, 0.25 );
DL.sPri8.setPosition( i, p.mX, p.mY, p.mWidth, p.mHeight );
DL.sPri8.setIndices( i );
}
DL.sPri8.draw_main( el * 6 );
/*
for( let i = mPlayer.length - 1; i >= 0; i-- ){
mPlayer[ i ].draw();
}
for( let i = mEnemy.length - 1; i >= 0; i-- ){
mEnemy[ i ].draw();
}
for( let i = mFire.length - 1; i >= 0; i-- ){
mFire[ i ].draw();
}
DL.DrawString( 4, 4, "SCORE " + mScore, 0xffffffff );
DL.DrawString( 76, 4, "HI-SCORE " + mHiScore, 0xffffffff );
if( mGameOver ){
DL.DrawString( 48, 64, "GAME OVER", 0xffffffff );
}
*/
GL.flush(); // 描画内容を画面に反映
}
function LoadImage( imf, imp )
{
DL.mTile8 = TUGames.GX.LoadTextureDiv( imf, TILE, TILE ); // 指定されたファイルをテクスチャ画像として分割して読み込む
DL.mTile32 = TUGames.GX.LoadTextureDiv( imp, CHRSIZE, CHRSIZE ); // 指定されたファイルをテクスチャ画像として分割して読み込む
DL.mTex8 = TUGames.Texture.Create2p( imf );
DL.sPri8 = new TUGames.PriRects( TUGames.GU.Format.T2F_V3F );
DL.sPri8.mTexture = TUGames.Texture.Create2p( imf );
Start();
}
window.onload = function()
{
document.addEventListener( 'keydown', ( ev ) =>{ ev.preventDefault(); } );
document.addEventListener( 'keyup' , ( ev ) =>{ ev.preventDefault(); } );
TUGames.GX.Init( "main", 180, 180 ); // キャンバスIDと描画領域を指定してライブラリ初期化
TUGames.GX.ClearColor( 0xff111111 );
let imf = new Image();
imf.onload = function()
{
let imp = new Image();
imp.onload = function()
{
LoadImage( imf, imp );
}
imp.src = "../assets/tile32.png";
}
imf.src = "../assets/tile8.png";
}
戻る back