"use strict";
var WIDTH = 480;
var HEIGHT = 360;
var LENGTH = 64000;
var Car = class extends TUGames.Sprite
{
constructor( textile, cidx )
{
super( 32, 64, textile, cidx, 1, 2 );
this.mDX = 0;
this.mSpeed = 0;
}
}
var Enemy = class extends Car
{
constructor( textile, spd )
{
super( textile, 25 );
this.X = TUGames.UT.Rnd( 200 ) + 140 - 16;
this.Y = -64;
this.mDX = ( TUGames.UT.Rnd( 13 ) - 6 ) / 4.0;
this.mSpeed = TUGames.UT.Rnd( spd ) + 10000;
}
}
var Player = class extends Car
{
constructor( textile )
{
super( textile, 24 );
this.mBrake = 0;
this.mSpeed = 6000;
this.X = WIDTH / 2 - 16;
this.Y = HEIGHT - 80;
}
tick()
{
if( TUGames.PF.IsKeyDown( 37 ) ){ // 引数で指定されたキーが押されている場合
if( this.mDX == 0 ){
this.X -= 2;
this.mSpeed -= 50;
}else if( this.mDX < 0 && this.mDX > -2 ){
this.mDX = 0;
}
}
if( TUGames.PF.IsKeyDown( 39 ) ){ // 引数で指定されたキーが押されている場合
if( this.mDX == 0 ){
this.X += 2;
this.mSpeed -= 50;
}else if( this.mDX > 0 && this.mDX < 2 ){
this.mDX = 0;
}
}
if( TUGames.PF.IsKeyDown( 90 ) ||
TUGames.PF.IsKeyDown( 40 ) ){ // 引数で指定されたキーが押されている場合
this.mSpeed = Math.max( 6000, this.mSpeed - 500 );
this.mBrake = true;
}
this.mSpeed += Math.min( 50, 1000000 / this.mSpeed );
this.X += this.mDX;
this.mDX -= Math.sign( this.mDX ) * Math.min( Math.abs( this.mDX ), 0.02 );
}
}
var Map =
[
[
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
[ 5, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 1, 1, ],
],[
[ 9, 9,10,10,16,18, 8,20,21, 8,19,17, 9, 8, 8, 8, ],
[ 9, 9,10,10,16, 8, 8, 8, 8, 8, 8,17, 9, 8, 8, 8, ],
[ 9, 8, 8, 8,16,18, 8,20,21, 8,19,17, 8, 8, 8, 8, ],
[ 9, 8, 8, 8,16, 8, 8, 8, 8, 8, 8,17, 8, 8, 8, 8, ],
[ 9, 9, 9, 9,16,18, 8,20,21, 8,19,17, 9, 8, 8, 8, ],
[ 9, 9, 9, 9,16, 8, 8, 8, 8, 8, 8,17, 9, 8, 8, 8, ],
[ 9, 8, 8, 8,16,18, 8,20,21, 8,19,17, 8, 8, 8, 8, ],
[ 9, 8, 8, 8,16, 8, 8, 8, 8, 8, 8,17, 8, 8, 8, 8, ],
[ 9, 9,10,11,16,18, 8,20,21, 8,19,17, 9, 8, 8, 8, ],
[ 9, 9,10,10,16, 8, 8, 8, 8, 8, 8,17, 9, 8, 8, 8, ],
[ 9, 8, 8, 8,16,18, 8,20,21, 8,19,17, 8, 8, 8, 8, ],
[ 9, 8, 8, 8,16, 8, 8, 8, 8, 8, 8,17, 8, 8, 8, 8, ],
[ 9, 9, 9, 9,16,18, 8,20,21, 8,19,17, 9, 8, 8, 8, ],
[ 9, 9, 9, 9,16, 8, 8, 8, 8, 8, 8,17, 9, 8, 8, 8, ],
[ 9, 8, 8, 8,16,18, 8,20,21, 8,19,17, 8, 8, 8, 8, ],
[ 9, 8, 8, 8,16, 8, 8, 8, 8, 8, 8,17, 8, 8, 8, 8, ],
]
];
function start( im )
{
TUGames.GX.Init( "main", 480, 360 ); // キャンバスIDと描画領域を指定してライブラリ初期化
let tex = TUGames.Texture.Create( 0x80, 0x80 );
tex.texSubImage2D( 0x00, 0x00, TUGames.TURawImage.CreateFromImage( im[ 0 ], 16 ) );
tex.texSubImage2D( 0x00, 0x40, TUGames.TURawImage.CreateFromImage( im[ 1 ], 16 ).clone( 0, 20, 128, 60 ) );
let ttc = new TUGames.TexTile( tex, 8, 0.5 / 8, 0.5 / 8 );
let field = new TUGames.BG( new TUGames.PriTile( 16, 16, 32, 32, 2, ttc ) );
field.setIndex_A3( Map );
let tf = new TUGames.TexFont( new TUGames.TexTile( tex, 16, 8 / 128.0, 10 / 128.0, 0.0, 0.5 ) );
tf.initHCode( 0x40, 0x20 );
let pt = [];
pt[ 0 ] = TUGames.PriStr.Create( "TIME" , tf, 4, 28 * 1 + 6, 0xffffffff, 0xffffffff, 0xff000000 );
pt[ 1 ] = TUGames.PriStr.Create( "" , tf, 12, 28 * 2 + 6, 0xffffffff, 0xffffffff, 0xff000000 );
pt[ 2 ] = TUGames.PriStr.Create( "SPEED", tf, 4, 28 * 4 + 6, 0xffffffff, 0xffffffff, 0xff000000 );
pt[ 3 ] = TUGames.PriStr.Create( "" , tf, 12, 28 * 5 + 6, 0xffffffff, 0xffffffff, 0xff000000 );
let player = new Player( ttc, 24 );
let enemy = [];
let py = 0;
let ani = -1;
TUGames.PF.StartLoop( 60, // fpsを指定してループを開始し、更新処理と描画処理を登録
// TUGames.PF.StartLoop( 1, // fpsを指定してループを開始し、更新処理と描画処理を登録
()=>{ // 更新処理
if( py - LENGTH > -0x200 && Map[ 1 ][ 0 ][ 4 ] == 16 ){ // ゴール目前に迫った場合
Map[ 1 ][ 0 ][ 4 ] = 13;
Map[ 1 ][ 0 ][ 5 ] = 13;
Map[ 1 ][ 0 ][ 6 ] = 13;
Map[ 1 ][ 0 ][ 7 ] = 14;
Map[ 1 ][ 0 ][ 8 ] = 15;
Map[ 1 ][ 0 ][ 9 ] = 13;
Map[ 1 ][ 0 ][ 10 ] = 13;
Map[ 1 ][ 0 ][ 11 ] = 13;
field.setIndex_A3( Map );
}
if( py - LENGTH > -0x200 + 276 ){ // ゴールした場合
player.mSpeed = 0;
return;
}
let tm = Math.floor( TUGames.PF.Count * 100 / 60 );
let st = "" + Math.floor( tm / 100 ) + "." + Math.floor( tm / 10 % 10 ) + ( tm % 10 );
pt[ 1 ].setString( st.padStart( 6, ' ' ) );
if( ani == 0 ){ // 衝突した場合
// wo.playDB( exp );
player.mSpeed = 0;
player.setCClm( 2 );
player.setWH( 64, 64 );
player.setCIdx( 40 );
player.X -= 16;
ani = 1;
}
if( ani > 0 ){ // 爆発アニメ中の場合
++ani;
if( ( ani & 7 ) == 0 ){
let i = ani >> 2;
if( i < 8 ){
player.setCIdx( 40 + i );
}
}
if( ani == 100 ){
ani = -1;
player.X = WIDTH / 2 - 16;
player.setCClm( 1 );
player.setWH( 32, 64 );
player.setCIdx( 24 );
player.mDX = 0;
player.mSpeed = 1000;
}
}
if( ( player.X < WIDTH / 2 - 16 - 112 || player.X > WIDTH / 2 - 16 + 112 ) && player.mSpeed >= 6000 && ani < 0 ){ // 壁に激突した場合
ani = 0;
}
player.tick();
if( ani >= 0 ){
player.mSpeed = 0;
}
let ps = Math.floor( player.mSpeed / 2.0 );
let s = Math.floor( ps / 100 ) + "." + ( Math.floor( ps / 10 ) % 10 ) + ( ps % 10 );
pt[ 3 ].setString( s.padStart( 6, ' ' ) );
if( ani < 0 ){
py += player.mSpeed / 4096;
}
let ds = player.mSpeed - 10000;
if( ds > 1000 && TUGames.UT.Rnd( 30 + enemy.length * 40 ) == 0 ){
enemy.push( new Enemy( ttc, ds ) );
}
for( let i = enemy.length - 1; i >= 0; i-- ){
let e = enemy[ i ];
if( ani < 0 && player.isCollision( e ) ){
let dx = e.X - player.X;
let dy = e.Y - player.Y;
let ss = player.mSpeed;
player.mSpeed = e.mSpeed;
e.mSpeed = ss;
player.mDX = -dx / 16;
e.mDX = dx / 16;
}
e.X += e.mDX;
e.Y += ( player.mSpeed - e.mSpeed ) / 4096;
if( e.X > WIDTH / 2 + 112 - 16 && e.mDX > 0 ){
e.mDX = -e.mDX;
}
if( e.X < WIDTH / 2 - 112 - 16 && e.mDX < 0 ){
e.mDX = -e.mDX;
}
if( e.Y > 360 ){
enemy.splice( i, 1 );
}
}
/*
if( wo.getFlagDoneDB() ){
if( !player.mBrake && player.mDX == 0 ){
wo.playDB( TUGames.TUWaveOut.CreateSquare( player.mSpeed / 512.0f, 100, 0x2000 ) );
}else{
wo.playDB( bra );
player.mBrake = false;
}
}
if( wobgm.getFlagDoneDB() ){
wobgm.playDB( wavbgm );
}
*/
},
()=>{ // 描画処理
TUGames.GX.Clear(); // 設定された背景色で画面初期化
field.drawFull( -16, Math.floor( py - LENGTH ), WIDTH, HEIGHT );
player.draw();
for( let i = 0; i < enemy.length; i++ ){
enemy[ i ].draw();
}
for( let i = 0; i < pt.length; i++ ){
pt[ i ].draw();
}
GL.flush(); // 描画内容を画面に反映
} );
}
window.onload = function()
{
document.addEventListener( 'keydown', ( ev ) =>{ ev.preventDefault(); } );
document.addEventListener( 'keyup' , ( ev ) =>{ ev.preventDefault(); } );
let fn = [ "../assets/8x8_4c_2bpp.png", "../assets/font_8x10.png" ];
let im = new Array( fn.length );
let cnt = 0;
for( let i = 0; i < fn.length; i++ ){
im[ i ] = new Image();
im[ i ].onload = function()
{
if( ++cnt == fn.length ){
start( im );
}
}
im[ i ].src = fn[ i ];
}
}
戻る back