mirror of
https://github.com/FlipsideCrypto/DefinitelyTyped.git
synced 2026-02-06 10:56:53 +00:00
Added definitions for the athenajs npm package (#29326)
* ADDED: initial files, more work needed * FIXED: more classes * FIXED: some fixes to incorrect types so that gods has no errors * IMPROVED: more strick tsconfig FIXED: tslint.json typo in filename * FIXED: npm test errors ADDED: UMD global var AthenaJS
This commit is contained in:
parent
52fe47713e
commit
e48af07ef9
784
types/athenajs/index.d.ts
vendored
Normal file
784
types/athenajs/index.d.ts
vendored
Normal file
@ -0,0 +1,784 @@
|
||||
// Type definitions for athenajs 0.1
|
||||
// Project: https://github.com/AthenaJS/athenajs
|
||||
// Definitions by: Nicolas Ramz <https://github.com/warpdesign>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
export as namespace AthenaJS;
|
||||
|
||||
export function Dom(sel?: string | HTMLElement): _Dom<HTMLElement>;
|
||||
|
||||
export class Scene {
|
||||
constructor(options?: SceneOptions);
|
||||
map: Map;
|
||||
hudScene: Scene | null;
|
||||
running: boolean;
|
||||
opacity: number;
|
||||
addObject(object: Drawable | Drawable[], layer?: number): Scene;
|
||||
animate(fxName: string, options: EffectOptions): Promise;
|
||||
bindEvents(eventList: string): void;
|
||||
debug(bool?: boolean): void;
|
||||
fadeIn(duration: number): Promise;
|
||||
fadeOut(duration: number): Promise;
|
||||
fadeInAndOut(inDuration: number, delay: number, outDuration: number): Promise;
|
||||
getOpacity(): number;
|
||||
getPlayTime(): number;
|
||||
load(type: string, src: string, id?: string): void;
|
||||
loadAudio(src: string, id?: string): void;
|
||||
loadImage(src: string, id?: string): void;
|
||||
loadMap(src: string, id?: string): void;
|
||||
notify(name: string, data?: JSObject): void;
|
||||
removeObject(obj: Drawable): void;
|
||||
setBackgroundImage(image: string|HTMLImageElement): void;
|
||||
setLayerPriority(layer: number, background: boolean): void;
|
||||
setMap(map: Map | JSObject, x?: number, y?: number): void;
|
||||
setOpacity(opacity: number): void;
|
||||
setup(): void;
|
||||
start(): void;
|
||||
stop(): void;
|
||||
}
|
||||
export class Game {
|
||||
constructor(options: GameOptions);
|
||||
bindEvents(eventList: string): void;
|
||||
setScene(scene: Scene): void;
|
||||
toggleFullscreen(): void;
|
||||
toggleSound(bool: boolean): void;
|
||||
toggleTileInspector(bool: boolean): void;
|
||||
togglePause(): void;
|
||||
scene: Scene;
|
||||
sound: boolean;
|
||||
}
|
||||
export class Drawable {
|
||||
constructor(type: string, options: DrawableOptions);
|
||||
addChild(child: Drawable): void;
|
||||
animate(name: string, options: JSObject): Promise;
|
||||
center(): Drawable;
|
||||
destroy(data?: any): void;
|
||||
moveTo(x: number, y: number, duration?: number): Drawable;
|
||||
notify(id: string, data?: JSObject): void;
|
||||
onCollision(object: Drawable): void;
|
||||
onEvent(eventType: string, data?: JSObject): void;
|
||||
playSound(id: string, options?: { pan?: boolean, loop?: false }): void;
|
||||
setBehavior(behavior: string | { new(sprite: Drawable, options?: JSObject): Behavior }, options?: JSObject): void;
|
||||
setScale(scale: number): void;
|
||||
getCurrentWidth(): number;
|
||||
getCurrentHeight(): number;
|
||||
getProperty(prop: string): any;
|
||||
setProperty(prop: string, value: any): void;
|
||||
setMask(mask: MaskOptions | null, exclude?: boolean): void;
|
||||
stopAnimate(endValue?: number): void;
|
||||
reset(): void;
|
||||
show(): void;
|
||||
hide(): void;
|
||||
type: string;
|
||||
width: number;
|
||||
height: number;
|
||||
x: number;
|
||||
y: number;
|
||||
vx: number;
|
||||
vy: number;
|
||||
canCollide: boolean;
|
||||
currentMovement: string;
|
||||
running: boolean;
|
||||
movable: boolean;
|
||||
behavior: Behavior;
|
||||
currentMap: Map;
|
||||
data: JSObject;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
export interface MaskOptions {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export interface MenuItem {
|
||||
text: string;
|
||||
selectable: boolean;
|
||||
visible: boolean;
|
||||
active?: boolean;
|
||||
}
|
||||
|
||||
export interface MenuOptions {
|
||||
title: string;
|
||||
color: string;
|
||||
menuItems: MenuItem[];
|
||||
}
|
||||
|
||||
export class Menu extends Drawable {
|
||||
constructor(id: string, options: MenuOptions);
|
||||
nextItem(): void;
|
||||
getSelectedItemIndex(): number;
|
||||
}
|
||||
|
||||
export class SimpleText extends Drawable {
|
||||
constructor(type: string, simpleTextOptions: SimpleTextOptions);
|
||||
getCurrentOffsetX(): number;
|
||||
getCurrentOffsetY(): number;
|
||||
setColor(color: string): void;
|
||||
setSize(width: number, height: number): void;
|
||||
setText(text: string): void;
|
||||
}
|
||||
export class Paint extends Drawable {
|
||||
constructor(type: string, paintOptions: PaintOptions);
|
||||
arc(cx: number, cy: number, r: number, starteAngle: number, endAngle: number, fillStyle: string, borderSize: number): void;
|
||||
fill(color?: string): void;
|
||||
circle(cx: number, cy: number, r: number, fillStyle?: string, borderWidth?: number, borderStyle?: string): void;
|
||||
rect(x: number, y: number, width: number, height: number, color: string): void;
|
||||
name: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
export class BitmapText extends Drawable {
|
||||
constructor(type: string, textOptions: BitmapTextOptions);
|
||||
setText(text: string): void;
|
||||
}
|
||||
|
||||
export class Sprite extends Drawable {
|
||||
constructor(type: string, spriteOptions: SpriteOptions);
|
||||
addAnimation(name: string, imgPath: string, options: AnimOptions): void;
|
||||
setAnimation(name: string, fn?: Callback, frameNum?: number, revert?: boolean): void;
|
||||
clearMove(): void;
|
||||
}
|
||||
|
||||
export interface pixelPos {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
export class Map {
|
||||
constructor(options: MapOptions);
|
||||
addObject(obj: Drawable, layerIndex?: number): void;
|
||||
addTileSet(tiles: TileDesc[]): void;
|
||||
checkMatrixForCollision(buffer: number[], matrixWidth: number, x: number, y: number, behavior: number): boolean;
|
||||
clear(tileNum?: number, behavior?: number): void;
|
||||
getTileBehaviorAtIndex(col: number, row: number): number;
|
||||
getTileIndexFromPixel(x: number, y: number): pixelPos;
|
||||
moveTo(x: number, y: number): void;
|
||||
respawn(): void;
|
||||
setData(map: Uint8Array, behaviors: Uint8Array): void;
|
||||
setEasing(easing: string): void;
|
||||
shift(startLine: number, height: number): void;
|
||||
updateTile(col: number, row: number, tileNum?: number, behavior?: number): void;
|
||||
duration: number;
|
||||
numRows: number;
|
||||
numCols: number;
|
||||
width: number;
|
||||
height: number;
|
||||
tileWidth: number;
|
||||
tileHeight: number;
|
||||
}
|
||||
|
||||
export class Tile {
|
||||
constructor(options: JSObject);
|
||||
static TYPE: {
|
||||
AIR: 1;
|
||||
WALL: 2;
|
||||
LADDER: 3;
|
||||
};
|
||||
offsetX: number;
|
||||
offsetY: number;
|
||||
width: number;
|
||||
height: number;
|
||||
|
||||
inertia: number;
|
||||
upCollide: boolean;
|
||||
downCollide: boolean;
|
||||
}
|
||||
|
||||
export interface TileDesc {
|
||||
offsetX: number;
|
||||
offsetY: number;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export interface MapOptions {
|
||||
src: string;
|
||||
tileWidth: number;
|
||||
tileHeight: number;
|
||||
width: number;
|
||||
height: number;
|
||||
viewportW?: number;
|
||||
viewportH?: number;
|
||||
buffer?: ArrayBuffer;
|
||||
}
|
||||
|
||||
export interface FXInstance {
|
||||
addFX(fxName: string, FxClass: { new(options: EffectOptions, display: Display): Effect }): void;
|
||||
}
|
||||
|
||||
export const FX: FXInstance;
|
||||
|
||||
export class _FX {
|
||||
/**
|
||||
* Creates the FX class, adding the linear easing
|
||||
*/
|
||||
constructor();
|
||||
|
||||
/**
|
||||
* Add a new Effect
|
||||
*/
|
||||
addFX(fxName: string, FxClass: { new(): Effect }): void;
|
||||
|
||||
/**
|
||||
* Retrieve an effect Class by its name
|
||||
*
|
||||
*/
|
||||
getEffect(fxName: string): Effect;
|
||||
|
||||
/**
|
||||
* Add a new easing function for other objects to use
|
||||
*
|
||||
*/
|
||||
addEasing(easingName: string, easingFn: (x?: number, t?: number, b?: number, c?: number, d?: number) => void): void;
|
||||
|
||||
/**
|
||||
* Retrieves an easing function
|
||||
*
|
||||
*/
|
||||
getEasing(easingName: string): (x?: number, t?: number, b?: number, c?: number, d?: number) => void;
|
||||
}
|
||||
|
||||
export interface EffectOptions {
|
||||
easing?: string;
|
||||
when?: string;
|
||||
startValue?: number;
|
||||
endValue?: number;
|
||||
duration?: number;
|
||||
}
|
||||
|
||||
export class Effect {
|
||||
width: number;
|
||||
height: number;
|
||||
buffer: RenderingContext;
|
||||
animProgress: number;
|
||||
startValue: number;
|
||||
ended: boolean;
|
||||
/**
|
||||
* This the class constructor. Default options are:
|
||||
*
|
||||
*/
|
||||
constructor(options: EffectOptions, display: Display);
|
||||
|
||||
/**
|
||||
* Changes the easing function used for the ffect
|
||||
*
|
||||
*/
|
||||
setEasing(easing: (x?: number, t?: number, b?: number, c?: number, d?: number) => void): void;
|
||||
|
||||
/**
|
||||
* Called when the ffect is started.
|
||||
*
|
||||
* This method can be overriden but the super should always be called
|
||||
*/
|
||||
start(): Promise;
|
||||
|
||||
/**
|
||||
* called when the effect is stopped
|
||||
*/
|
||||
stop(object: any, setEndValue: any): void;
|
||||
|
||||
/**
|
||||
* Calculates current animation process
|
||||
*
|
||||
* This method can be overridden but the super should always be calle first
|
||||
*/
|
||||
process(ctx: RenderingContext, fxCtx?: RenderingContext, obj?: any): boolean;
|
||||
}
|
||||
|
||||
// why do we need this ?
|
||||
export type RenderingContext = CanvasRenderingContext2D;
|
||||
|
||||
export interface DisplayOptions {
|
||||
width: number;
|
||||
height: number;
|
||||
type: string;
|
||||
layers?: boolean[];
|
||||
name: string;
|
||||
}
|
||||
|
||||
export class Display {
|
||||
/**
|
||||
* Creates a new Display instance
|
||||
*
|
||||
*/
|
||||
constructor(options: DisplayOptions, target: string | HTMLElement);
|
||||
|
||||
/**
|
||||
* Creates a new (offscreen) drawing buffer
|
||||
*
|
||||
*/
|
||||
getBuffer(width: number, height: number): RenderingContext;
|
||||
|
||||
/**
|
||||
* Toggles fullscreen display scaling
|
||||
*/
|
||||
toggleFullscreen(): void;
|
||||
|
||||
/**
|
||||
* Changes the zIndex property of the specified layer canvas
|
||||
*
|
||||
*/
|
||||
setLayerZIndex(layer: number, zIndex: number): void;
|
||||
|
||||
/**
|
||||
* Clears a canvas display buffer
|
||||
*
|
||||
*/
|
||||
clearScreen(ctx: RenderingContext): void;
|
||||
|
||||
/**
|
||||
* Clears every rendering buffer, including the special fxCtx one
|
||||
*/
|
||||
clearAllScreens(): void;
|
||||
|
||||
/**
|
||||
* Changes the (CSS) opacity of a canvas
|
||||
*
|
||||
*/
|
||||
setCanvasOpacity(canvas: HTMLElement, opacity: number): void;
|
||||
|
||||
/**
|
||||
* Renders the specified scene
|
||||
*
|
||||
*/
|
||||
renderScene(scene: Scene): void;
|
||||
|
||||
/**
|
||||
* Prepares the canvas before rendering images.
|
||||
*
|
||||
* Explanation: during development, I noticed that the very first time
|
||||
* the ctx.drawImage() was used to draw onto a canvas, it took a very long time,
|
||||
* like at least 10ms for a very small 32x32 pixels drawImage.
|
||||
*
|
||||
* Subsequent calls do not have this problem and are instant.
|
||||
* Maybe some ColorFormat conversion happens.
|
||||
*
|
||||
* This method makes sure that when the game starts rendering, we don't have
|
||||
* any of these delays that can impact gameplay and alter the gameplay experience
|
||||
* in a negative way.
|
||||
*/
|
||||
prepareCanvas(resources: JSObject[]): void;
|
||||
|
||||
/**
|
||||
* Starts an animation on the display
|
||||
*
|
||||
*/
|
||||
animate(fxName: string, options: EffectOptions, context: RenderingContext): Promise;
|
||||
|
||||
/**
|
||||
* stops current animation
|
||||
*
|
||||
* TODO
|
||||
*/
|
||||
stopAnimate(fxName?: string): void;
|
||||
|
||||
/**
|
||||
* Executes an effect on a frame at a given time
|
||||
*
|
||||
*/
|
||||
executeFx(ctx: RenderingContext, fxCtx: RenderingContext, obj: Drawable, time: number, when: string): void;
|
||||
|
||||
/**
|
||||
* Clears every display layer and clears fx queues
|
||||
*/
|
||||
clearDisplay(): void;
|
||||
}
|
||||
|
||||
export const InputManager: _InputManager;
|
||||
|
||||
export class MapEvent {
|
||||
/**
|
||||
* Creates a new MapEvent
|
||||
*
|
||||
*/
|
||||
constructor(map: Map);
|
||||
|
||||
/**
|
||||
* Resets the MapEvent switches, events and items
|
||||
*/
|
||||
reset(): void;
|
||||
|
||||
/**
|
||||
* Adds a new [`Drawable`]{#item} onto the map
|
||||
*
|
||||
*/
|
||||
addItem(id: string, item: Drawable): void;
|
||||
|
||||
/**
|
||||
* Returns an item
|
||||
*
|
||||
*/
|
||||
getItem(id: string): Drawable | undefined;
|
||||
|
||||
// TODO: ability to trigger an event once a switch has been modified
|
||||
setSwitch(id: string, bool: boolean): void;
|
||||
|
||||
toggleSwitch(id: string): void;
|
||||
|
||||
/**
|
||||
* Retrieves a switch from the map using its id
|
||||
*
|
||||
*/
|
||||
getSwitch(id: string): any;
|
||||
|
||||
/**
|
||||
* checks of conditions of specified trigger are valid
|
||||
*
|
||||
*/
|
||||
checkConditions(trigger: JSObject): boolean;
|
||||
|
||||
handleAction(options: JSObject): void;
|
||||
|
||||
handleEvent(options: JSObject): boolean;
|
||||
|
||||
/**
|
||||
* Schedule adding a new object to the map
|
||||
*/
|
||||
scheduleSprite(spriteId: string, spriteOptions: JSObject, delay: number): Drawable;
|
||||
|
||||
/**
|
||||
* Add a new wave of objects to the map
|
||||
* Used for example when the player triggers apparition of several enemies or bonuses
|
||||
*
|
||||
* @related {Wave}
|
||||
*/
|
||||
handleWave(options: JSObject): boolean;
|
||||
|
||||
endWave(): void;
|
||||
|
||||
triggerEvent(id: string): void;
|
||||
|
||||
isEventTriggered(id: string): boolean;
|
||||
}
|
||||
|
||||
export class Behavior {
|
||||
vx: number;
|
||||
vy: number;
|
||||
gravity: number;
|
||||
sprite: Drawable;
|
||||
constructor(sprite: Drawable, options?: JSObject);
|
||||
onUpdate(timestamp: number): void;
|
||||
onVXChange?(vx: number): void;
|
||||
onVYChange?(vy: number): void;
|
||||
|
||||
/**
|
||||
* Returns current mapEvent
|
||||
*
|
||||
*/
|
||||
getMapEvent(): MapEvent;
|
||||
reset(): void;
|
||||
}
|
||||
|
||||
export interface _AudioManager {
|
||||
audioCache: JSObject;
|
||||
enabled: boolean;
|
||||
/**
|
||||
* Adds a new sound element to the audio cache.
|
||||
* *Note* if a sound with the same id has already been added, it will be replaced
|
||||
* by the new one.
|
||||
*
|
||||
*/
|
||||
addSound(id: string, element: HTMLAudioElement): void;
|
||||
/**
|
||||
* Toggles global sound playback
|
||||
*
|
||||
*/
|
||||
toggleSound(bool: boolean): void;
|
||||
/**
|
||||
* Plays the specified sound with `id`.
|
||||
*
|
||||
*/
|
||||
play(id: string, loop?: boolean, volume?: number, panning?: number): any;
|
||||
/**
|
||||
* Stops playing the sound id
|
||||
*
|
||||
*/
|
||||
stop(id: string, instanceId: any): void;
|
||||
}
|
||||
|
||||
export const AudioManager: _AudioManager;
|
||||
|
||||
export interface Res {
|
||||
id: string;
|
||||
type: string;
|
||||
src: string;
|
||||
}
|
||||
|
||||
export type Callback = (...args: any[]) => void;
|
||||
|
||||
export interface _NotificationManager {
|
||||
notify(name: string, data?: JSObject): void;
|
||||
}
|
||||
|
||||
export const NotificationManager: _NotificationManager;
|
||||
|
||||
export interface _ResourceManager {
|
||||
addResources(resource: Res, group?: string): Promise;
|
||||
getCanvasFromImage(image: HTMLImageElement): HTMLCanvasElement;
|
||||
getResourceById(id: string, group?: string, fullObject?: boolean): any;
|
||||
loadResources(group: string, progressCb?: Callback, errorCb?: Callback): void;
|
||||
loadImage(res: Res, group?: string): Promise;
|
||||
loadAudio(res: Res, group?: string): Promise;
|
||||
newResourceFromPool(id: string): any;
|
||||
registerScript(id: string, elt: any, poolSize?: number): void;
|
||||
}
|
||||
|
||||
export const ResourceManager: _ResourceManager;
|
||||
|
||||
export interface _InputManager {
|
||||
/**
|
||||
* A list of common keyCodes
|
||||
*/
|
||||
KEYS: {
|
||||
'UP': 38,
|
||||
'DOWN': 40,
|
||||
'LEFT': 37,
|
||||
'RIGHT': 39,
|
||||
'SPACE': 32,
|
||||
'ENTER': 13,
|
||||
'ESCAPE': 27,
|
||||
'CTRL': 17
|
||||
};
|
||||
/**
|
||||
* List of common pad buttons
|
||||
*/
|
||||
PAD_BUTTONS: {
|
||||
32: 1, // Face (main) buttons
|
||||
FACE_0: 1,
|
||||
FACE_3: 2,
|
||||
FACE_4: 3,
|
||||
LEFT_SHOULDER: 4, // Top shoulder buttons
|
||||
RIGHT_SHOULDER: 5,
|
||||
LEFT_SHOULDER_BOTTOM: 6, // Bottom shoulder buttons
|
||||
RIGHT_SHOULDER_BOTTOM: 7,
|
||||
SELECT: 8,
|
||||
START: 9,
|
||||
LEFT_ANALOGUE_STICK: 10, // Analogue sticks (if depressible)
|
||||
RIGHT_ANALOGUE_STICK: 11,
|
||||
38: 12, // Directional (discrete) pad
|
||||
40: 13,
|
||||
37: 14,
|
||||
39: 15
|
||||
};
|
||||
axes: JSObject;
|
||||
newGamepadPollDelay: number;
|
||||
gamepadSupport: boolean;
|
||||
recording: boolean;
|
||||
playingEvents: boolean;
|
||||
playingPos: number;
|
||||
/*recordedEvents: Array,*/
|
||||
pad: null;
|
||||
latches: JSObject;
|
||||
keyPressed: JSObject;
|
||||
padPressed: JSObject;
|
||||
keyCb: JSObject;
|
||||
enabled: boolean;
|
||||
inputMode: string;
|
||||
// virtual joystick instance
|
||||
dPadJoystick: null;
|
||||
jPollInterval: number;
|
||||
/**
|
||||
* Initializes the InputManager with a reference to the game.
|
||||
*
|
||||
* This method prepares the InputManager by reseting keyboard states/handlers and
|
||||
* set current inputMode
|
||||
*
|
||||
*/
|
||||
init(): void;
|
||||
/**
|
||||
* Starts recording input events. They are stored into `InputManager.recordedEvents`
|
||||
*/
|
||||
startRecordingEvents(): void;
|
||||
/**
|
||||
* Stops recording events.
|
||||
*/
|
||||
stopRecordingEvents(): void;
|
||||
/**
|
||||
* After events have been reccorded they can be played back using this method.
|
||||
*/
|
||||
playRecordedEvents(): void;
|
||||
/**
|
||||
* Sets next key states using recorded events
|
||||
*
|
||||
* TODO: add an optional callback to be called at the end of the playback
|
||||
* so that demo can be looped.
|
||||
*/
|
||||
nextRecordedEvents(): void;
|
||||
/**
|
||||
* Saves current event state onto the recordedEvents stack
|
||||
*/
|
||||
/**
|
||||
* Changes input mode
|
||||
*
|
||||
*/
|
||||
setInputMode(mode: string): void;
|
||||
/**
|
||||
* Returns an object with the state of all keys
|
||||
*/
|
||||
getAllKeysStatus(): JSObject;
|
||||
getKeyStatus(key: string, latch: boolean): boolean;
|
||||
isKeyDown(key: string|number, latch?: boolean): boolean;
|
||||
/**
|
||||
* Install callback that gets called when a key is pressed/released
|
||||
*
|
||||
*/
|
||||
installKeyCallback(key: string, event: string, callback: (key: string, event: string) => void): void;
|
||||
removeKeyCallback(key: string, event: string, callback: () => void): void;
|
||||
clearEvents(): void;
|
||||
}
|
||||
|
||||
export interface Promise {
|
||||
then(val?: () => any): Promise;
|
||||
catch(val?: () => any): Promise;
|
||||
}
|
||||
|
||||
/* Deferred */
|
||||
export class Deferred {
|
||||
constructor();
|
||||
/**
|
||||
* Creates and immediately resolves a new deferred.
|
||||
*
|
||||
*/
|
||||
static resolve(val?: any): Promise;
|
||||
promise: Promise;
|
||||
reject(val: any): void;
|
||||
resolve(val: any): void;
|
||||
}
|
||||
|
||||
/* Dom support */
|
||||
export interface _Dom<TElement> extends Iterable<TElement> {
|
||||
[key: number]: TElement;
|
||||
length: number;
|
||||
css(prop: string, val: string): _Dom<TElement>;
|
||||
css(prop: JSObject): _Dom<TElement>;
|
||||
css(prop: string): string|null;
|
||||
find(selector: string): _Dom<TElement>;
|
||||
appendTo(selector: string | _Dom<TElement> | HTMLElement): _Dom<TElement>;
|
||||
attr(att: string, val: string): _Dom<TElement>;
|
||||
attr(att: JSObject): _Dom<TElement>;
|
||||
addClass(classes: string): _Dom<TElement>;
|
||||
removeClass(classes: string): _Dom<TElement>;
|
||||
html(str: string): _Dom<TElement>;
|
||||
show(): _Dom<TElement>;
|
||||
hide(): _Dom<TElement>;
|
||||
}
|
||||
|
||||
/* Game Support */
|
||||
export interface GameOptions {
|
||||
name: string;
|
||||
showFps: boolean;
|
||||
width: number;
|
||||
height: number;
|
||||
debug: boolean;
|
||||
scene?: Scene;
|
||||
target?: string | HTMLElement;
|
||||
sound?: boolean;
|
||||
}
|
||||
|
||||
export interface SceneOptions {
|
||||
name?: string;
|
||||
resources?: Res[];
|
||||
opacity?: number;
|
||||
layers?: number;
|
||||
hudScene?: Scene;
|
||||
}
|
||||
|
||||
export interface DrawableOptions {
|
||||
x?: number;
|
||||
y?: number;
|
||||
behavior?: { new(sprite: Drawable, options?: JSObject): Behavior };
|
||||
canCollide?: boolean;
|
||||
canCollideFriendBullet?: boolean;
|
||||
collideGroup?: number;
|
||||
objectId?: string;
|
||||
layer?: number;
|
||||
map?: Map;
|
||||
visible?: boolean;
|
||||
pool?: number;
|
||||
}
|
||||
|
||||
export interface SimpleTextOptions extends DrawableOptions {
|
||||
text?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
fontFace?: string;
|
||||
fontSize?: string;
|
||||
fontStyle?: string;
|
||||
fontWeight?: string;
|
||||
align?: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export interface PaintOptions extends DrawableOptions {
|
||||
width?: number;
|
||||
height?: number;
|
||||
color?: string;
|
||||
lineHeight?: number;
|
||||
}
|
||||
|
||||
export interface BitmapTextOptions extends DrawableOptions {
|
||||
width?: number;
|
||||
height?: number;
|
||||
offsetX: number;
|
||||
startY: number;
|
||||
charWidth: number;
|
||||
charHeight: number;
|
||||
imageId?: string;
|
||||
imageSrc?: string;
|
||||
scrollOffsetX?: number;
|
||||
scrollOffsetY?: number;
|
||||
text?: string;
|
||||
size?: string;
|
||||
}
|
||||
|
||||
export interface SpriteOptions extends DrawableOptions {
|
||||
easing?: string;
|
||||
imageId?: string;
|
||||
animations?: Animations;
|
||||
data?: JSObject;
|
||||
}
|
||||
|
||||
export interface AnimOptions {
|
||||
numFrames: number;
|
||||
frameWidth: number;
|
||||
frameHeight: number;
|
||||
frameDuration: number;
|
||||
offsetX?: number;
|
||||
offsetY?: number;
|
||||
frameSpacing?: number;
|
||||
}
|
||||
|
||||
export interface AnimationObject {
|
||||
frameDuration?: number;
|
||||
frames: Array<{
|
||||
offsetX: number;
|
||||
offsetY: number;
|
||||
width: number;
|
||||
height: number;
|
||||
hitBox?: {
|
||||
x: number;
|
||||
y: number;
|
||||
x2: number;
|
||||
y2: number;
|
||||
},
|
||||
plane?: number;
|
||||
}>;
|
||||
loop?: number;
|
||||
speed?: number;
|
||||
}
|
||||
|
||||
export interface JSObject {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface Animations {
|
||||
[key: string]: AnimationObject;
|
||||
}
|
||||
|
||||
export interface GameEvent {
|
||||
type: string;
|
||||
data: JSObject;
|
||||
}
|
||||
18
types/athenajs/test/bitmaptext.ts
Normal file
18
types/athenajs/test/bitmaptext.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { BitmapText } from 'athenajs';
|
||||
|
||||
const bitmap: BitmapText = new BitmapText('myBitmap', {
|
||||
size: 'big',
|
||||
width: 180,
|
||||
height: 32,
|
||||
visible: false,
|
||||
scrollOffsetX: 0,
|
||||
scrollOffsetY: 0,
|
||||
text: 'pause',
|
||||
offsetX: 34,
|
||||
startY: 36,
|
||||
charWidth: 18,
|
||||
charHeight: 18,
|
||||
imageId: 'font'
|
||||
});
|
||||
|
||||
bitmap.center();
|
||||
28
types/athenajs/test/deferred.ts
Normal file
28
types/athenajs/test/deferred.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { Deferred } from 'athenajs';
|
||||
|
||||
let def: Deferred;
|
||||
|
||||
// static Deferred.resolve
|
||||
Deferred.resolve(true).then(() => {
|
||||
console.log('resolved');
|
||||
})
|
||||
.then(() => {
|
||||
console.log('resolved');
|
||||
});
|
||||
|
||||
def = new Deferred();
|
||||
|
||||
// resolve/reject
|
||||
def.resolve(10);
|
||||
|
||||
def = new Deferred();
|
||||
def.reject(false);
|
||||
def.promise.then(() => {
|
||||
console.log('done');
|
||||
})
|
||||
.then(() => {
|
||||
console.log('real done');
|
||||
})
|
||||
.catch(() => {
|
||||
console.log('oops');
|
||||
});
|
||||
33
types/athenajs/test/dom.ts
Normal file
33
types/athenajs/test/dom.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { Dom } from 'athenajs';
|
||||
|
||||
const div = Dom('div');
|
||||
const body = Dom(document.body);
|
||||
const domElt: HTMLElement = body[0];
|
||||
|
||||
// Dom.appendTo
|
||||
div.appendTo(body).show().hide();
|
||||
div.appendTo(domElt);
|
||||
|
||||
const str: string | null = body.css('display');
|
||||
const i: number = body.length;
|
||||
|
||||
// Dom.css
|
||||
body.css('display', ' block');
|
||||
body.css({ display: 'none' });
|
||||
body.css('display', 'block');
|
||||
|
||||
// Dom.find
|
||||
body.find('div').appendTo('body');
|
||||
|
||||
// Dom.attr
|
||||
body.attr('data-test', 'hi');
|
||||
body.attr({ 'data-test2': 'foo' });
|
||||
|
||||
// Dom.addClass/Dom.removeClass
|
||||
body.addClass('foo').removeClass('foo');
|
||||
|
||||
// Dom.show/hide
|
||||
body.show().hide();
|
||||
|
||||
// Dom.html
|
||||
body.html('<div>foo</div>');
|
||||
36
types/athenajs/test/drawable.ts
Normal file
36
types/athenajs/test/drawable.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { Behavior, Drawable, Map } from 'athenajs';
|
||||
|
||||
const sprite = new Drawable('mySprite', {
|
||||
objectId: 'my Rocking Sprite',
|
||||
layer: 0
|
||||
});
|
||||
const sprite2 = new Drawable('mySprite2', {});
|
||||
|
||||
sprite.addChild(sprite2);
|
||||
sprite.animate('Fade', {
|
||||
duration: 100
|
||||
});
|
||||
sprite.moveTo(0, 0).notify('yo!');
|
||||
|
||||
sprite.onCollision(sprite2);
|
||||
sprite.onEvent('boom');
|
||||
sprite.playSound('explosion', {
|
||||
pan: true
|
||||
});
|
||||
sprite.setBehavior('stupid');
|
||||
sprite.setBehavior(Behavior);
|
||||
sprite.setScale(1.0);
|
||||
|
||||
const str: string = sprite.getProperty('strProp');
|
||||
sprite.setProperty('strProp', str);
|
||||
|
||||
sprite.setMask({
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 100,
|
||||
height: 100
|
||||
});
|
||||
|
||||
sprite.setMask(null);
|
||||
|
||||
sprite.stopAnimate(10);
|
||||
23
types/athenajs/test/game.ts
Normal file
23
types/athenajs/test/game.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { Game, Scene } from 'athenajs';
|
||||
|
||||
let myScene: Scene = new Scene();
|
||||
let sound: boolean;
|
||||
|
||||
const game: Game = new Game({
|
||||
name: 'myGame',
|
||||
showFps: true,
|
||||
width: 320,
|
||||
height: 200,
|
||||
debug: true,
|
||||
scene: myScene,
|
||||
target: 'body',
|
||||
sound: true
|
||||
});
|
||||
|
||||
game.setScene(myScene);
|
||||
game.toggleSound(false);
|
||||
game.toggleTileInspector(true);
|
||||
game.toggleFullscreen();
|
||||
game.togglePause();
|
||||
myScene = game.scene;
|
||||
sound = game.sound;
|
||||
29
types/athenajs/test/map.ts
Normal file
29
types/athenajs/test/map.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { Map, TileDesc } from 'athenajs';
|
||||
|
||||
const map = new Map({
|
||||
src: "tiles",
|
||||
tileWidth: 32,
|
||||
tileHeight: 32,
|
||||
width: 29 * 32,
|
||||
height: 8 * 32,
|
||||
viewportW: 320,
|
||||
viewportH: 200
|
||||
});
|
||||
const tiles: TileDesc[] = [];
|
||||
const mapContent: Uint8Array = new Uint8Array(10);
|
||||
const behaviors: Uint8Array = new Uint8Array(10);
|
||||
|
||||
for (let row = 0; row < 8; row++) {
|
||||
for (let col = 0; col < 29; col++) {
|
||||
tiles.push({
|
||||
offsetX: col * 32,
|
||||
offsetY: row * 32,
|
||||
width: 32,
|
||||
height: 32
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
map.addTileSet(tiles);
|
||||
|
||||
map.setData(mapContent, behaviors);
|
||||
12
types/athenajs/test/paint.ts
Normal file
12
types/athenajs/test/paint.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { Paint } from 'athenajs';
|
||||
|
||||
const paint: Paint = new Paint('brush', {
|
||||
width: 300,
|
||||
height: 200,
|
||||
color: 'red'
|
||||
});
|
||||
|
||||
paint.color = 'red';
|
||||
paint.circle(0, 0, 150);
|
||||
paint.circle(0, 0, 100, 'green');
|
||||
paint.circle(0, 0, 50, 'green', 2, 'blue');
|
||||
58
types/athenajs/test/scene.ts
Normal file
58
types/athenajs/test/scene.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import { Game, Scene, Drawable, Map } from 'athenajs';
|
||||
|
||||
let num: number;
|
||||
|
||||
const hudScene = new Scene();
|
||||
const myScene: Scene = new Scene({
|
||||
name: 'myScene',
|
||||
resources: [{
|
||||
id: 'myRes',
|
||||
src: 'src',
|
||||
type: 'image'
|
||||
}],
|
||||
opacity: 1,
|
||||
layers: 0,
|
||||
hudScene
|
||||
});
|
||||
|
||||
num = myScene.getOpacity();
|
||||
myScene.setOpacity(10);
|
||||
|
||||
const sprite = new Drawable('mySprite', {});
|
||||
|
||||
myScene.debug(false);
|
||||
myScene.bindEvents('gameover');
|
||||
myScene.addObject(sprite);
|
||||
myScene.animate('Fade', {
|
||||
easing: 'linear'
|
||||
}).then(() => {
|
||||
console.log('effect ended');
|
||||
});
|
||||
myScene.fadeIn(1000).then(() => {
|
||||
myScene.fadeOut(2000);
|
||||
myScene.fadeInAndOut(2000, 1000, 1000);
|
||||
console.log(myScene.getPlayTime());
|
||||
});
|
||||
|
||||
myScene.load('image', 'img/foo.png');
|
||||
myScene.load('image', 'img/background.png', 'bg');
|
||||
myScene.loadAudio('sound/yeah.mp3');
|
||||
myScene.loadImage('img/bar.gif');
|
||||
myScene.loadAudio('sound/yeah.mp3');
|
||||
myScene.loadAudio('maps/map.json');
|
||||
|
||||
myScene.setBackgroundImage(new Image());
|
||||
myScene.setLayerPriority(10, true);
|
||||
|
||||
myScene.notify('ready');
|
||||
|
||||
myScene.removeObject(sprite);
|
||||
|
||||
myScene.setMap({});
|
||||
myScene.setMap(new Map({
|
||||
src: 'img/tiles.png',
|
||||
tileWidth: 24,
|
||||
tileHeight: 32,
|
||||
width: 240,
|
||||
height: 320
|
||||
}));
|
||||
17
types/athenajs/test/simpletext.ts
Normal file
17
types/athenajs/test/simpletext.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { SimpleText } from 'athenajs';
|
||||
|
||||
const myText: SimpleText = new SimpleText('MyText', {
|
||||
text: 'yop',
|
||||
width: 100,
|
||||
height: 200,
|
||||
fontFace: 'Arial',
|
||||
fontSize: '20px',
|
||||
fontStyle: 'italic',
|
||||
fontWeight: '300',
|
||||
align: 'center',
|
||||
color: 'white'
|
||||
});
|
||||
|
||||
myText.setSize(100, 200);
|
||||
myText.setText('Hi!');
|
||||
myText.setColor('rgba(0,0,0,.4');
|
||||
28
types/athenajs/test/sprite.ts
Normal file
28
types/athenajs/test/sprite.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { Sprite } from 'athenajs';
|
||||
|
||||
const sprite: Sprite = new Sprite('mySprite', {
|
||||
imageId: 'tiles',
|
||||
animations: {
|
||||
anim1: {
|
||||
frameDuration: 1,
|
||||
frames: [{
|
||||
offsetX: 396,
|
||||
offsetY: 2,
|
||||
width: 64,
|
||||
height: 96,
|
||||
hitBox: {
|
||||
x: 1,
|
||||
y: 4,
|
||||
x2: 62,
|
||||
y2: 95
|
||||
},
|
||||
plane: 0
|
||||
}],
|
||||
loop: 0
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sprite.setAnimation('anim1', () => {
|
||||
sprite.setAnimation('anim1', () => { console.log('the end!'); }, 0, true);
|
||||
});
|
||||
35
types/athenajs/test/tetris/flash_lines.ts
Normal file
35
types/athenajs/test/tetris/flash_lines.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { Paint, PaintOptions } from 'athenajs';
|
||||
|
||||
interface FlashOptions extends PaintOptions {
|
||||
lineHeight: number;
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
}
|
||||
|
||||
export default class FlashLines extends Paint {
|
||||
lines: number[];
|
||||
lineHeight: number;
|
||||
|
||||
constructor(name: string, options: FlashOptions) {
|
||||
super('flashlines', options);
|
||||
|
||||
this.lines = [];
|
||||
this.lineHeight = options.lineHeight;
|
||||
}
|
||||
|
||||
flash() {
|
||||
return this.animate('Fade', {
|
||||
startValue: 1,
|
||||
endValue: 0,
|
||||
duration: 400,
|
||||
loop: 2
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
for (const line of this.lines) {
|
||||
this.rect(0, line * this.lineHeight, this.width, this.lineHeight, 'white');
|
||||
}
|
||||
}
|
||||
}
|
||||
469
types/athenajs/test/tetris/grid.ts
Normal file
469
types/athenajs/test/tetris/grid.ts
Normal file
@ -0,0 +1,469 @@
|
||||
import { Scene, Map, Tile, Dom, SimpleText, AudioManager as AM, Deferred } from "athenajs";
|
||||
import Shape from "./shape";
|
||||
import FlashLines from "./flash_lines";
|
||||
|
||||
// size constants
|
||||
const MAP_ROWS = 22;
|
||||
const MAP_COLS = 12;
|
||||
const TILE_WIDTH = 20;
|
||||
const TILE_HEIGHT = 20;
|
||||
// tile offsets in the spritesheet
|
||||
const MAP_TILES_OFFSET_Y = 440;
|
||||
const WALL_TILE_OFFSET_X = 140;
|
||||
const BACK_TILE_OFFSET_X = 160;
|
||||
// wall tile number
|
||||
const WALL_TILE = 8;
|
||||
// game width
|
||||
const TOTAL_WIDTH = 800;
|
||||
const TOTAL_HEIGHT = 600;
|
||||
// speed (drop delay) at start
|
||||
const START_TIMING = 1200;
|
||||
// speed increase at each level
|
||||
const LEVEL_TIMING = 55;
|
||||
|
||||
class Grid extends Scene {
|
||||
// game parameters
|
||||
score: number;
|
||||
level: number;
|
||||
timing: number;
|
||||
lines: number;
|
||||
scoreTable: number[];
|
||||
|
||||
// game sprites
|
||||
// current tetris shape
|
||||
shape: Shape;
|
||||
// next tetris shape
|
||||
nextShape: Shape;
|
||||
// next tetris string
|
||||
nextString: SimpleText;
|
||||
// score
|
||||
scoreString: SimpleText;
|
||||
// "line:"
|
||||
linesString: SimpleText;
|
||||
// "level:"
|
||||
levelString: SimpleText;
|
||||
// "pause:"
|
||||
pauseString: SimpleText;
|
||||
// flashing lines
|
||||
flashLines: FlashLines;
|
||||
// ->, <-
|
||||
controls: SimpleText;
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
resources: [
|
||||
{
|
||||
id: "tiles",
|
||||
type: "image",
|
||||
src: "img/tetris_tiles.png"
|
||||
},
|
||||
{
|
||||
id: "gameover",
|
||||
type: "audio",
|
||||
src: "sound/gameover.mp3"
|
||||
},
|
||||
{
|
||||
id: "ground",
|
||||
type: "audio",
|
||||
src: "sound/ground.mp3"
|
||||
},
|
||||
{
|
||||
id: "level",
|
||||
type: "audio",
|
||||
src: "sound/level.mp3"
|
||||
},
|
||||
{
|
||||
id: "lines",
|
||||
type: "audio",
|
||||
src: "sound/lines.mp3"
|
||||
},
|
||||
{
|
||||
id: "lines_tetris",
|
||||
type: "audio",
|
||||
src: "sound/lines_tetris.mp3"
|
||||
},
|
||||
{
|
||||
id: "move",
|
||||
type: "audio",
|
||||
src: "sound/move.mp3"
|
||||
},
|
||||
{
|
||||
id: "pause",
|
||||
type: "audio",
|
||||
src: "sound/pause.mp3"
|
||||
},
|
||||
{
|
||||
id: "rotate",
|
||||
type: "audio",
|
||||
src: "sound/rotate.mp3"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// here we keep game-related properties
|
||||
this.score = 0;
|
||||
this.level = 0;
|
||||
this.lines = 0;
|
||||
this.timing = START_TIMING;
|
||||
this.scoreTable = [40, 100, 300, 1200];
|
||||
|
||||
// we only need to catch the 'ground' event from the 'shape' element
|
||||
this.bindEvents("shape:ground");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate tileset for the tetris map, mostly hardcoded stuff
|
||||
*
|
||||
*/
|
||||
generateTileSet() {
|
||||
// create the list of all tiles for the map
|
||||
const tiles = [
|
||||
{
|
||||
offsetX: WALL_TILE_OFFSET_X,
|
||||
offsetY: MAP_TILES_OFFSET_Y,
|
||||
width: TILE_WIDTH,
|
||||
height: TILE_HEIGHT
|
||||
}
|
||||
];
|
||||
|
||||
// add a tile for each color
|
||||
for (let i = 0, offset = 0; i < 7; ++i, offset += TILE_WIDTH) {
|
||||
tiles.push({
|
||||
offsetX: offset,
|
||||
offsetY: MAP_TILES_OFFSET_Y,
|
||||
width: TILE_WIDTH,
|
||||
height: TILE_HEIGHT
|
||||
});
|
||||
}
|
||||
|
||||
tiles.push({
|
||||
offsetX: BACK_TILE_OFFSET_X,
|
||||
offsetY: MAP_TILES_OFFSET_Y,
|
||||
width: TILE_WIDTH,
|
||||
height: TILE_HEIGHT
|
||||
});
|
||||
|
||||
return tiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the map of the game, adding walls around the playground
|
||||
*/
|
||||
createMap() {
|
||||
// first create the map with an empty buffer
|
||||
const map = new Map({
|
||||
src: "tiles",
|
||||
tileWidth: TILE_WIDTH,
|
||||
tileHeight: TILE_WIDTH,
|
||||
width: TILE_WIDTH * MAP_COLS,
|
||||
height: TILE_HEIGHT * MAP_ROWS,
|
||||
buffer: new ArrayBuffer(MAP_COLS * MAP_ROWS * 2)
|
||||
});
|
||||
|
||||
// finally add the tileset
|
||||
map.addTileSet(this.generateTileSet());
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
resetMap() {
|
||||
const map = this.map;
|
||||
|
||||
map.clear(0, Tile.TYPE.AIR);
|
||||
|
||||
// set map tiles around the playground as wall tiles
|
||||
for (let i = 0; i < map.numRows; ++i) {
|
||||
map.updateTile(0, i, WALL_TILE, Tile.TYPE.WALL);
|
||||
map.updateTile(map.numCols - 1, i, WALL_TILE, Tile.TYPE.WALL);
|
||||
}
|
||||
|
||||
for (let i = 0; i < map.numCols; ++i) {
|
||||
map.updateTile(i, map.numRows - 1, WALL_TILE, Tile.TYPE.WALL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the tile sprite that will be moved by the player
|
||||
*/
|
||||
createShapes() {
|
||||
this.shape = new Shape("shape", {
|
||||
data: {
|
||||
speed: this.timing
|
||||
}
|
||||
});
|
||||
|
||||
this.nextShape = new Shape("nextShape", {
|
||||
x: 610,
|
||||
y: 110
|
||||
});
|
||||
|
||||
this.nextShape.movable = false;
|
||||
this.nextString = new SimpleText("nextString", {
|
||||
text: "Next",
|
||||
x: 620,
|
||||
y: 70
|
||||
});
|
||||
|
||||
this.scoreString = new SimpleText("scoreString", {
|
||||
text: "Score: 0",
|
||||
x: 50,
|
||||
y: 70
|
||||
});
|
||||
|
||||
this.linesString = new SimpleText("linesString", {
|
||||
text: "Lines: 0",
|
||||
x: 50,
|
||||
y: 120
|
||||
});
|
||||
|
||||
this.levelString = new SimpleText("levelString", {
|
||||
text: "Level: 0",
|
||||
x: 50,
|
||||
y: 170
|
||||
});
|
||||
|
||||
this.pauseString = new SimpleText("pauseString", {
|
||||
text: "Pause",
|
||||
x: 380,
|
||||
y: 550,
|
||||
visible: false
|
||||
});
|
||||
|
||||
this.controls = new SimpleText("controlsString", {
|
||||
text: "Controls:\narrow keys",
|
||||
x: 50,
|
||||
y: 220
|
||||
});
|
||||
|
||||
this.flashLines = new FlashLines("flash", {
|
||||
x: (TOTAL_WIDTH - TILE_WIDTH * MAP_COLS) / 2 + TILE_WIDTH,
|
||||
y: (TOTAL_HEIGHT - TILE_HEIGHT * MAP_ROWS) / 2,
|
||||
width: TILE_WIDTH * (MAP_COLS - 2),
|
||||
lineHeight: TILE_HEIGHT
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the scene is ready: generates the map and adds the player's shape
|
||||
* sprite onto the screen
|
||||
*/
|
||||
setup() {
|
||||
this.createShapes();
|
||||
|
||||
this.map = this.createMap();
|
||||
}
|
||||
|
||||
start() {
|
||||
const map = this.map;
|
||||
|
||||
this.setBackgroundImage("img/background.png");
|
||||
|
||||
// center map
|
||||
this.setMap(
|
||||
map,
|
||||
(TOTAL_WIDTH - map.width) / 2,
|
||||
(TOTAL_HEIGHT - map.height) / 2
|
||||
);
|
||||
|
||||
map.addObject(this.shape);
|
||||
|
||||
this.addObject([
|
||||
this.nextShape,
|
||||
this.nextString,
|
||||
this.linesString,
|
||||
this.scoreString,
|
||||
this.levelString,
|
||||
this.pauseString,
|
||||
this.flashLines,
|
||||
this.controls
|
||||
]);
|
||||
|
||||
this.reset();
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.score = 0;
|
||||
this.level = 0;
|
||||
this.lines = 0;
|
||||
this.timing = START_TIMING;
|
||||
this.resetMap();
|
||||
this.shape.moveToTop();
|
||||
|
||||
this.shape.setRandomShape();
|
||||
this.nextShape.setRandomShape();
|
||||
this.linesString.setText("Lines: " + this.lines);
|
||||
this.scoreString.setText("Score: " + this.score);
|
||||
this.levelString.setText("Level: " + this.level);
|
||||
|
||||
this.shape.movable = true;
|
||||
this.shape.behavior.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on game over, simply displays the score in an alert box and restarts the game
|
||||
*/
|
||||
gameover() {
|
||||
AM.play("gameover");
|
||||
alert("game over!" + this.score);
|
||||
this.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called whenever an event that has been registered is received
|
||||
*
|
||||
*/
|
||||
onEvent(event: any) {
|
||||
const nextShape = this.nextShape;
|
||||
const shape = this.shape;
|
||||
|
||||
switch (event.type) {
|
||||
case "shape:ground":
|
||||
// update the map with the new shape
|
||||
this.updateMap();
|
||||
// check for lines to remove
|
||||
this.removeLinesFromMap(
|
||||
event.data.startLine,
|
||||
event.data.numRows
|
||||
).then(() => {
|
||||
shape.setShape(nextShape.shapeName, nextShape.rotation);
|
||||
nextShape.setRandomShape();
|
||||
|
||||
this.shape.moveToTop();
|
||||
|
||||
// we may have a game over here: if the shape collides with another one
|
||||
if (!this.shape.snapTile(0, 0, false)) {
|
||||
this.gameover();
|
||||
} else {
|
||||
this.shape.movable = true;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when a shape has reached the ground: in this case
|
||||
* we simply update the map using the shape's matrix
|
||||
*/
|
||||
updateMap() {
|
||||
const shape = this.shape;
|
||||
const data = this.shape.shape;
|
||||
const map = this.map;
|
||||
const pos = map.getTileIndexFromPixel(shape.x, shape.y);
|
||||
const buffer = shape.getMatrix();
|
||||
const rows = data.height / map.tileHeight;
|
||||
const cols = data.width / map.tileWidth;
|
||||
|
||||
for (let j = 0; j < rows; ++j) {
|
||||
for (let i = 0; i < cols; ++i) {
|
||||
if (buffer[j * cols + i]) {
|
||||
map.updateTile(pos.x + i, pos.y + j, data.color, Tile.TYPE.WALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the number of lines that contains no hole, starting from
|
||||
* startLine up to startLine + height
|
||||
*
|
||||
*/
|
||||
getLinesToRemove(startLine: number, height: number): number[] {
|
||||
console.log("[Grid] getLinesToRemove()");
|
||||
const map = this.map;
|
||||
const lines: number[] = [];
|
||||
let lastLine = startLine + height - 1;
|
||||
|
||||
// avoid bottom ground
|
||||
if (lastLine > map.numRows - 2) lastLine = map.numRows - 2;
|
||||
|
||||
for (let j = lastLine; j >= startLine; --j) {
|
||||
let hole = false;
|
||||
for (let i = 1; i < map.numCols - 1; ++i) {
|
||||
hole = hole || map.getTileBehaviorAtIndex(i, j) !== Tile.TYPE.WALL;
|
||||
}
|
||||
if (!hole) {
|
||||
lines.push(j);
|
||||
}
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates level + level object's text
|
||||
*/
|
||||
updateLevel() {
|
||||
const oldLevel = this.level;
|
||||
this.level = Math.floor(this.lines / 10);
|
||||
this.levelString.setText("Level: " + this.level);
|
||||
this.timing = START_TIMING - this.level * LEVEL_TIMING;
|
||||
this.shape.data['speed'] = this.timing;
|
||||
oldLevel !== this.level && AM.play("level");
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the player's score using line number & current level
|
||||
*
|
||||
*/
|
||||
increaseScore(lines: number) {
|
||||
this.score +=
|
||||
this.scoreTable[lines - 1] + this.level * this.scoreTable[lines - 1];
|
||||
this.lines += lines;
|
||||
this.linesString.setText("Lines: " + this.lines);
|
||||
this.scoreString.setText("Score: " + this.score);
|
||||
|
||||
if (lines === 4) {
|
||||
AM.play("lines_tetris");
|
||||
} else {
|
||||
AM.play("lines");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes lines from the map, shifting the map as needed, and adding
|
||||
* empty tiles at the top
|
||||
*
|
||||
*/
|
||||
removeLinesFromMap(startLine: number, height: number) {
|
||||
const map = this.map;
|
||||
const lines = this.getLinesToRemove(startLine, height);
|
||||
|
||||
// no full lines detected
|
||||
if (!lines.length) {
|
||||
return Deferred.resolve(true);
|
||||
}
|
||||
|
||||
this.flashLines.lines = lines;
|
||||
return this.flashLines.flash().then(() => {
|
||||
// shift the map for each line to remove
|
||||
for (let i = 0; i < lines.length; ++i) {
|
||||
map.shift(lines[i] + i, 1);
|
||||
}
|
||||
|
||||
// add wall at each side of the new lines
|
||||
for (let i = 0; i < height; ++i) {
|
||||
for (let j = 0; j < map.numCols; ++j) {
|
||||
map.updateTile(j, i, 0, Tile.TYPE.AIR);
|
||||
}
|
||||
map.updateTile(0, i, 8, Tile.TYPE.WALL);
|
||||
map.updateTile(map.numCols - 1, i, 8, Tile.TYPE.WALL);
|
||||
}
|
||||
|
||||
Dom('.athena-game').addClass('shake-vertical shake-constant');
|
||||
setTimeout(() => {
|
||||
Dom('.athena-game').removeClass('shake-vertical shake-constant');
|
||||
}, 300);
|
||||
|
||||
this.increaseScore(lines.length);
|
||||
this.updateLevel();
|
||||
});
|
||||
}
|
||||
|
||||
pause(isRunning: boolean) {
|
||||
this.pauseString.visible = !isRunning;
|
||||
AM.play("pause");
|
||||
}
|
||||
}
|
||||
|
||||
export default Grid;
|
||||
256
types/athenajs/test/tetris/shape.ts
Normal file
256
types/athenajs/test/tetris/shape.ts
Normal file
@ -0,0 +1,256 @@
|
||||
import { Sprite, Tile, AudioManager as AM, JSObject } from 'athenajs';
|
||||
import ShapeBehavior from './shape_behavior';
|
||||
|
||||
interface shapeDescription {
|
||||
name: string;
|
||||
width: number;
|
||||
height: number;
|
||||
color: number;
|
||||
rotations: number[][];
|
||||
}
|
||||
|
||||
class Shape extends Sprite {
|
||||
shapes: shapeDescription[];
|
||||
// current shape
|
||||
shape: shapeDescription;
|
||||
shapeName: string;
|
||||
// current shape rotation
|
||||
rotation: number;
|
||||
|
||||
constructor(name: string, options = {}) {
|
||||
super(name, {
|
||||
imageId: 'tiles',
|
||||
easing: 'linear',
|
||||
// behavior: ShapeBehavior,
|
||||
// ...options
|
||||
});
|
||||
|
||||
/**
|
||||
* Hardcoded tetris shapes. In addition to its width/height, color and
|
||||
* name, each shape contains a rotation a matrix for each rotation
|
||||
* that looks like:
|
||||
*
|
||||
* ---
|
||||
* |J
|
||||
* |JJJ
|
||||
* |
|
||||
* ---
|
||||
*
|
||||
* Matrix: [1, 0, 0,
|
||||
* 1, 1, 1
|
||||
* 0, 0, 0]
|
||||
*
|
||||
* Each shape contains four different rotations
|
||||
*/
|
||||
this.shapes = [
|
||||
{
|
||||
name: 'I', width: 80, height: 80, color: 7, rotations: [
|
||||
[0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0]
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'J', width: 60, height: 60, color: 6, rotations: [
|
||||
[1, 0, 0, 1, 1, 1, 0, 0, 0],
|
||||
[0, 1, 1, 0, 1, 0, 0, 1, 0],
|
||||
[0, 0, 0, 1, 1, 1, 0, 0, 1],
|
||||
[0, 1, 0, 0, 1, 0, 1, 1, 0]
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'L', width: 60, height: 60, color: 5, rotations: [
|
||||
[0, 0, 1, 1, 1, 1, 0, 0, 0],
|
||||
[0, 1, 0, 0, 1, 0, 0, 1, 1],
|
||||
[0, 0, 0, 1, 1, 1, 1, 0, 0],
|
||||
[1, 1, 0, 0, 1, 0, 0, 1, 0]
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'O', width: 80, height: 60, color: 4, rotations: [
|
||||
[0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0],
|
||||
[0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0],
|
||||
[0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0],
|
||||
[0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0]
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'S', width: 60, height: 60, color: 3, rotations: [
|
||||
[0, 1, 1, 1, 1, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 1, 1, 0, 0, 1],
|
||||
[0, 0, 0, 0, 1, 1, 1, 1, 0],
|
||||
[1, 0, 0, 1, 1, 0, 0, 1, 0]
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Z', width: 60, height: 60, color: 2, rotations: [
|
||||
[1, 1, 0, 0, 1, 1, 0, 0, 0],
|
||||
[0, 0, 1, 0, 1, 1, 0, 1, 0],
|
||||
[0, 0, 0, 1, 1, 0, 0, 1, 1],
|
||||
[0, 1, 0, 1, 1, 0, 1, 0, 0]
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'T', width: 60, height: 60, color: 1, rotations: [
|
||||
[0, 1, 0, 1, 1, 1, 0, 0, 0],
|
||||
[0, 1, 0, 0, 1, 1, 0, 1, 0],
|
||||
[0, 0, 0, 1, 1, 1, 0, 1, 0],
|
||||
[0, 1, 0, 1, 1, 0, 0, 1, 0]
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
this.addAnimations();
|
||||
this.setShape('S', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the shape at the top center of the map
|
||||
*/
|
||||
moveToTop(): void {
|
||||
if (this.shape) {
|
||||
const map = this.currentMap;
|
||||
const col = Math.floor(((map.width - this.shape.width) / 2) / map.tileWidth);
|
||||
|
||||
this.moveTo(col * map.tileWidth, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the sprite's shape and rotation
|
||||
*
|
||||
*/
|
||||
setShape(name: string, rotation: number): void {
|
||||
this.shapeName = name;
|
||||
this.rotation = rotation;
|
||||
this.shape = this.shapes.find((shape) => shape.name === this.shapeName) || this.shapes[0];
|
||||
this.setAnimation(`${name}${rotation}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a new random shape
|
||||
*/
|
||||
setRandomShape(): void {
|
||||
const shapeName = this.shapes[Math.random() * 7 | 0].name;
|
||||
const rotation = Math.random() * 4 | 0;
|
||||
|
||||
console.log(`[Shape] setRandomShape() - ${shapeName}`);
|
||||
|
||||
if (!this.movable) {
|
||||
this.animate('Fade', {
|
||||
duration: 200,
|
||||
startValue: 1,
|
||||
endValue: 0
|
||||
}).then(() => {
|
||||
this.setShape(shapeName, rotation);
|
||||
this.animate('Fade', {
|
||||
duration: 200,
|
||||
startValue: 0,
|
||||
endValue: 1
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.setShape(shapeName, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current matrix for the shape
|
||||
*
|
||||
*/
|
||||
getMatrix(rotation = -1): number[] {
|
||||
return this.shape.rotations[rotation === -1 ? this.rotation : rotation];
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the shape on the map by a certain number of tiles, optionnaly sending an event
|
||||
* of a collision is detected
|
||||
*
|
||||
*/
|
||||
snapTile(horizontal = 0, vertical = 0, notify = true, noSound = false): boolean {
|
||||
const map = this.currentMap;
|
||||
const buffer = this.getMatrix();
|
||||
const tilePos = map.getTileIndexFromPixel(this.x, this.y);
|
||||
const newX = tilePos.x + horizontal;
|
||||
const newY = tilePos.y + vertical;
|
||||
|
||||
// first check there is no collision with walls
|
||||
if (!map.checkMatrixForCollision(buffer, this.shape.width, newX, newY, Tile.TYPE.WALL)) {
|
||||
this.x += horizontal * map.tileWidth;
|
||||
this.y += vertical * map.tileHeight;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// if a collision was detected and vertical == 1 it means the shape reached
|
||||
// the ground: in this case we send a notification for the grid
|
||||
// and make the shape stop responding to user input or timer
|
||||
if (vertical === 1) {
|
||||
this.movable = false;
|
||||
if (notify) {
|
||||
AM.play('ground');
|
||||
this.notify('ground', {
|
||||
startLine: tilePos.y,
|
||||
numRows: this.shape.height / map.tileHeight
|
||||
});
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches to the next shape's rotation, if no collision found onto the map
|
||||
*/
|
||||
nextRotation(): void {
|
||||
let matrix: number[];
|
||||
let newRotation = this.rotation + 1;
|
||||
|
||||
const map = this.currentMap;
|
||||
const tilePos = map.getTileIndexFromPixel(this.x, this.y);
|
||||
|
||||
// cycles if last position reached
|
||||
if (newRotation > 3) {
|
||||
newRotation = 0;
|
||||
}
|
||||
|
||||
// get current shape + position matrix
|
||||
matrix = this.getMatrix(newRotation);
|
||||
|
||||
if (!map.checkMatrixForCollision(matrix, this.shape.width, tilePos.x, tilePos.y, Tile.TYPE.WALL)) {
|
||||
// change shape rotation if no collision detected
|
||||
this.setShape(this.shapeName, newRotation);
|
||||
AM.play('rotate');
|
||||
} else {
|
||||
console.log('rotation not possible');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We add a new Sprite animation for each combination of rotation + shapeType:
|
||||
* {
|
||||
* 'J0', // first rotation of the J Shape
|
||||
* ....
|
||||
* 'J3', // last rotation of the J Shape
|
||||
* 'L0', // first rotation of the L shape
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
addAnimations(): void {
|
||||
// shape sprite images start at the top of the image file
|
||||
let offsetY = 0;
|
||||
|
||||
this.shapes.forEach((shape) => {
|
||||
let offsetX = 0;
|
||||
for (let i = 0; i < 4; ++i) {
|
||||
this.addAnimation(`${shape.name}${i}`, 'tiles', {
|
||||
offsetY, offsetX, frameWidth: shape.width, frameHeight: shape.height, frameDuration: 1, numFrames: 1
|
||||
});
|
||||
offsetX += shape.width;
|
||||
}
|
||||
offsetY += shape.height;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default Shape;
|
||||
140
types/athenajs/test/tetris/shape_behavior.ts
Normal file
140
types/athenajs/test/tetris/shape_behavior.ts
Normal file
@ -0,0 +1,140 @@
|
||||
import { Behavior, InputManager as IM, AudioManager as AM, Sprite, Drawable } from 'athenajs';
|
||||
import Shape from './shape';
|
||||
|
||||
/**
|
||||
* Simple Behavior for the tetris shape that moves the shape on cursor key press
|
||||
* and when timer is reached
|
||||
*
|
||||
*
|
||||
* @see {Behavior}
|
||||
*/
|
||||
class ShapeBehavior extends Behavior {
|
||||
state: number;
|
||||
lastRotation: number;
|
||||
ts: number;
|
||||
LONG_DELAY: number;
|
||||
SMALL_DELAY: number;
|
||||
delay: number;
|
||||
key: number;
|
||||
timerEnabled: boolean;
|
||||
startTime: number;
|
||||
|
||||
constructor(sprite: Shape, options?: any) {
|
||||
super(sprite as Drawable, options);
|
||||
|
||||
// current behavior state: moving right, left, top, bottom
|
||||
this.state = 0;
|
||||
// when lastRotation happened
|
||||
this.lastRotation = 0;
|
||||
this.ts = 0;
|
||||
// long delay before starting to move quickly
|
||||
this.LONG_DELAY = 250;
|
||||
// repeat-delay once the long delay has been reached
|
||||
this.SMALL_DELAY = 70;
|
||||
|
||||
this.reset();
|
||||
}
|
||||
|
||||
reset() {
|
||||
IM.clearEvents();
|
||||
|
||||
// current delay before repeating a key
|
||||
this.delay = this.LONG_DELAY;
|
||||
this.key = 0;
|
||||
this.timerEnabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the player keeps a key down, we wait for a long delay before
|
||||
* quickly moving the picece: we don't want to miss interpret his move.
|
||||
*
|
||||
* If he quickly releases the key and quickly presses it, we have to
|
||||
* react though
|
||||
*
|
||||
*/
|
||||
ready(state: number, timestamp: number): boolean {
|
||||
// if the player pressed a different key
|
||||
// we react immediately but have to wait a long_delay
|
||||
// before repeating the key if he keeps pressing it
|
||||
if (this.state !== state) {
|
||||
this.ts = timestamp;
|
||||
this.state = state;
|
||||
this.delay = this.LONG_DELAY;
|
||||
return true;
|
||||
} else if (timestamp - this.ts > this.delay) {
|
||||
// player keeps pressing the key for a long delay
|
||||
// we react and set delay to a smaller one to quickly
|
||||
// repeat the action
|
||||
this.ts = timestamp;
|
||||
this.delay = this.SMALL_DELAY;
|
||||
return true;
|
||||
} else {
|
||||
// repeat delay not reached
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks tetris timer
|
||||
*
|
||||
*/
|
||||
timer(timestamp: number): boolean {
|
||||
const sprite = this.sprite;
|
||||
if (!this.startTime) {
|
||||
this.startTime = timestamp;
|
||||
} else {
|
||||
if (timestamp - this.startTime > sprite.data['speed']) {
|
||||
// timer reached
|
||||
this.startTime = timestamp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
checkKeyDelay(key: number, timestamp: number, x: number, y: number): void {
|
||||
const sprite = this.sprite as Shape;
|
||||
if (this.ready(key, timestamp)) {
|
||||
sprite.snapTile(x, y) && AM.play('move');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when updating the shape's position
|
||||
* and updates its position when cursor keys are pressed or
|
||||
* the timer happened
|
||||
*/
|
||||
onUpdate(timestamp: number) {
|
||||
const sprite = this.sprite as Shape;
|
||||
|
||||
// debug: stop the timer when t key is pressed
|
||||
if (IM.isKeyDown(84)) {
|
||||
this.timerEnabled = !this.timerEnabled;
|
||||
return;
|
||||
}
|
||||
|
||||
// first check timer
|
||||
if (this.timerEnabled && this.timer(timestamp)) {
|
||||
// timer reached: move the sprite down
|
||||
sprite.snapTile(0, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Then checks cursor keys
|
||||
if (IM.isKeyDown('DOWN')) {
|
||||
this.checkKeyDelay(1, timestamp, 0, 1);
|
||||
} else if (IM.isKeyDown('LEFT')) {
|
||||
this.checkKeyDelay(2, timestamp, -1, 0);
|
||||
} else if (IM.isKeyDown('RIGHT')) {
|
||||
this.checkKeyDelay(3, timestamp, 1, 0);
|
||||
} else if ((IM.isKeyDown('UP') || IM.isKeyDown('SPACE')) && (timestamp - this.lastRotation > 150)) {
|
||||
this.lastRotation = timestamp;
|
||||
sprite.nextRotation();
|
||||
} else if (this.state) {
|
||||
// key released
|
||||
this.ready(0, timestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default ShapeBehavior;
|
||||
11
types/athenajs/test/tetris/tetris.ts
Normal file
11
types/athenajs/test/tetris/tetris.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Game } from 'athenajs';
|
||||
import Grid from './grid';
|
||||
|
||||
const tetris = new Game({
|
||||
name: 'athena-tetris',
|
||||
showFps: true,
|
||||
debug: true,
|
||||
width: 800,
|
||||
height: 600,
|
||||
scene: new Grid()
|
||||
});
|
||||
40
types/athenajs/tsconfig.json
Normal file
40
types/athenajs/tsconfig.json
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"noEmit": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"es5",
|
||||
"es6",
|
||||
"es2015.iterable",
|
||||
"dom"
|
||||
],
|
||||
"module": "commonjs",
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"test/dom.ts",
|
||||
"test/deferred.ts",
|
||||
"test/game.ts",
|
||||
"test/scene.ts",
|
||||
"test/drawable.ts",
|
||||
"test/simpletext.ts",
|
||||
"test/paint.ts",
|
||||
"test/bitmaptext.ts",
|
||||
"test/sprite.ts",
|
||||
"test/map.ts",
|
||||
"test/tetris/tetris.ts",
|
||||
"test/tetris/shape.ts",
|
||||
"test/tetris/grid.ts",
|
||||
"test/tetris/shape_behavior.ts",
|
||||
"test/tetris/flash_lines.ts"
|
||||
]
|
||||
}
|
||||
3
types/athenajs/tslint.json
Normal file
3
types/athenajs/tslint.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json"
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user