added tween features

This commit is contained in:
Joe Weaver 2020-12-01 14:04:24 -05:00
parent 5bf6e96778
commit b8849b4c84
18 changed files with 191 additions and 49 deletions

View File

@ -55,6 +55,7 @@ export default abstract class GameNode implements Positioned, Unique, Updateable
protected layer: Layer; protected layer: Layer;
tweens: TweenManager; tweens: TweenManager;
rotation: number; rotation: number;
alpha: number;
constructor(){ constructor(){
this.input = InputReceiver.getInstance(); this.input = InputReceiver.getInstance();
@ -64,6 +65,7 @@ export default abstract class GameNode implements Positioned, Unique, Updateable
this.emitter = new Emitter(); this.emitter = new Emitter();
this.tweens = new TweenManager(this); this.tweens = new TweenManager(this);
this.rotation = 0; this.rotation = 0;
this.alpha = 1;
} }
/*---------- POSITIONED ----------*/ /*---------- POSITIONED ----------*/
@ -254,5 +256,6 @@ export enum TweenableProperties{
posY = "positionY", posY = "positionY",
scaleX = "scaleX", scaleX = "scaleX",
scaleY = "scaleY", scaleY = "scaleY",
rotation = "rotation" rotation = "rotation",
alpha = "alpha"
} }

View File

@ -21,6 +21,8 @@ export class TweenData {
/** An array of the effects on the properties of the object */ /** An array of the effects on the properties of the object */
effects: [{ effects: [{
property: TweenableProperties; property: TweenableProperties;
resetOnComplete: boolean;
initialValue: number;
start: any; start: any;
end: any; end: any;
ease: EaseFunctionType; ease: EaseFunctionType;

View File

@ -44,6 +44,13 @@ export default class TweenManager {
tween.loop = loop; tween.loop = loop;
} }
// Set the initial values
for(let effect of tween.effects){
if(effect.resetOnComplete){
effect.initialValue = this.owner[effect.property];
}
}
// Start the tween running // Start the tween running
tween.animationState = AnimationState.PLAYING; tween.animationState = AnimationState.PLAYING;
tween.elapsedTime = 0; tween.elapsedTime = 0;
@ -80,7 +87,15 @@ export default class TweenManager {
*/ */
stop(key: string): void { stop(key: string): void {
if(this.tweens.has(key)){ if(this.tweens.has(key)){
this.tweens.get(key).animationState = AnimationState.STOPPED; let tween = this.tweens.get(key);
tween.animationState = AnimationState.STOPPED;
// Return to the initial values
for(let effect of tween.effects){
if(effect.resetOnComplete){
this.owner[effect.property] = effect.initialValue;
}
}
} }
} }
@ -103,7 +118,7 @@ export default class TweenManager {
tween.elapsedTime -= tween.duration; tween.elapsedTime -= tween.duration;
} else { } else {
// We aren't looping and can't reverse, so stop // We aren't looping and can't reverse, so stop
tween.animationState = AnimationState.STOPPED; this.stop(key);
} }
} }
@ -113,7 +128,7 @@ export default class TweenManager {
tween.reversing = false; tween.reversing = false;
tween.elapsedTime -= 2*tween.duration; tween.elapsedTime -= 2*tween.duration;
} else { } else {
tween.animationState = AnimationState.STOPPED; this.stop(key);
} }
} }

View File

@ -66,19 +66,41 @@ export default class CanvasRenderer extends RenderingManager {
} }
}); });
// Render tilemaps let tilemapIndex = 0;
tilemaps.forEach(tilemap => { let tilemapLength = tilemaps.length;
this.renderTilemap(tilemap);
});
// Render visible set let visibleSetIndex = 0;
visibleSet.forEach(node => { let visibleSetLength = visibleSet.length;
if(node.visible){
this.renderNode(node); while(tilemapIndex < tilemapLength || visibleSetIndex < visibleSetLength){
// Check conditions where we've already reached the edge of one list
if(tilemapIndex >= tilemapLength){
// Only render the remaining visible set
let node = visibleSet[visibleSetIndex++];
if(node.visible){
this.renderNode(node);
}
continue;
} }
});
// Render the uiLayers if(visibleSetIndex >= visibleSetLength){
// Only render tilemaps
this.renderTilemap(tilemaps[tilemapIndex++]);
continue;
}
// Render whichever is further down
if(tilemaps[tilemapIndex].getLayer().getDepth() <= visibleSet[visibleSetIndex].getLayer().getDepth()){
this.renderTilemap(tilemaps[tilemapIndex++]);
} else {
let node = visibleSet[visibleSetIndex++];
if(node.visible){
this.renderNode(node);
}
}
}
// Render the uiLayers on top of everything else
uiLayers.forEach(key => uiLayers.get(key).getItems().forEach(node => this.renderNode(<CanvasNode>node))); uiLayers.forEach(key => uiLayers.get(key).getItems().forEach(node => this.renderNode(<CanvasNode>node)));
} }
@ -100,6 +122,8 @@ export default class CanvasRenderer extends RenderingManager {
this.ctx.setTransform(xScale, 0, 0, yScale, (node.position.x - this.origin.x)*this.zoom, (node.position.y - this.origin.y)*this.zoom); this.ctx.setTransform(xScale, 0, 0, yScale, (node.position.x - this.origin.x)*this.zoom, (node.position.y - this.origin.y)*this.zoom);
this.ctx.rotate(node.rotation); this.ctx.rotate(node.rotation);
let globalAlpha = this.ctx.globalAlpha;
this.ctx.globalAlpha = node.alpha;
if(node instanceof AnimatedSprite){ if(node instanceof AnimatedSprite){
this.renderAnimatedSprite(<AnimatedSprite>node); this.renderAnimatedSprite(<AnimatedSprite>node);
@ -111,6 +135,7 @@ export default class CanvasRenderer extends RenderingManager {
this.renderUIElement(<UIElement>node); this.renderUIElement(<UIElement>node);
} }
this.ctx.globalAlpha = globalAlpha;
this.ctx.setTransform(1, 0, 0, 1, 0, 0); this.ctx.setTransform(1, 0, 0, 1, 0, 0);
} }

View File

@ -107,7 +107,11 @@ export default class ResourceManager {
* @param key The key of the loaded image * @param key The key of the loaded image
*/ */
public getImage(key: string): HTMLImageElement { public getImage(key: string): HTMLImageElement {
return this.images.get(key); let image = this.images.get(key);
if(image === undefined){
throw `There is no image associated with key "${key}"`
}
return image;
} }
public spritesheet(key: string, path: string): void { public spritesheet(key: string, path: string): void {

View File

@ -13,6 +13,8 @@ import Slider from "../../Nodes/UIElements/Slider";
import TextInput from "../../Nodes/UIElements/TextInput"; import TextInput from "../../Nodes/UIElements/TextInput";
import Rect from "../../Nodes/Graphics/Rect"; import Rect from "../../Nodes/Graphics/Rect";
import ResourceManager from "../../ResourceManager/ResourceManager"; import ResourceManager from "../../ResourceManager/ResourceManager";
import UILayer from "../Layers/UILayer";
import ParallaxLayer from "../Layers/ParallaxLayer";
export default class CanvasNodeFactory { export default class CanvasNodeFactory {
protected scene: Scene; protected scene: Scene;
@ -75,7 +77,10 @@ export default class CanvasNodeFactory {
// Add instance to scene // Add instance to scene
instance.setScene(this.scene); instance.setScene(this.scene);
instance.id = this.scene.generateId(); instance.id = this.scene.generateId();
this.scene.getSceneGraph().addNode(instance);
if(!(this.scene.isParallaxLayer(layerName) || this.scene.isUILayer(layerName))){
this.scene.getSceneGraph().addNode(instance);
}
// Add instance to layer // Add instance to layer
layer.addNode(instance); layer.addNode(instance);
@ -91,7 +96,10 @@ export default class CanvasNodeFactory {
// Add instance fo scene // Add instance fo scene
instance.setScene(this.scene); instance.setScene(this.scene);
instance.id = this.scene.generateId(); instance.id = this.scene.generateId();
this.scene.getSceneGraph().addNode(instance);
if(!(this.scene.isParallaxLayer(layerName) || this.scene.isUILayer(layerName))){
this.scene.getSceneGraph().addNode(instance);
}
// Add instance to layer // Add instance to layer
layer.addNode(instance); layer.addNode(instance);

View File

@ -180,7 +180,7 @@ export default class Scene implements Updateable, Renderable {
* @param depth The depth of the layer * @param depth The depth of the layer
*/ */
addLayer(name: string, depth?: number): Layer { addLayer(name: string, depth?: number): Layer {
if(this.layers.has(name) || this.uiLayers.has(name)){ if(this.layers.has(name) || this.parallaxLayers.has(name) || this.uiLayers.has(name)){
throw `Layer with name ${name} already exists`; throw `Layer with name ${name} already exists`;
} }
@ -202,13 +202,13 @@ export default class Scene implements Updateable, Renderable {
* @param depth The depth of the layer * @param depth The depth of the layer
*/ */
addParallaxLayer(name: string, parallax: Vec2, depth?: number): ParallaxLayer { addParallaxLayer(name: string, parallax: Vec2, depth?: number): ParallaxLayer {
if(this.layers.has(name) || this.uiLayers.has(name)){ if(this.layers.has(name) || this.parallaxLayers.has(name) || this.uiLayers.has(name)){
throw `Layer with name ${name} already exists`; throw `Layer with name ${name} already exists`;
} }
let layer = new ParallaxLayer(this, name, parallax); let layer = new ParallaxLayer(this, name, parallax);
this.layers.add(name, layer); this.parallaxLayers.add(name, layer);
if(depth){ if(depth){
layer.setDepth(depth); layer.setDepth(depth);
@ -222,7 +222,7 @@ export default class Scene implements Updateable, Renderable {
* @param name The name of the new UIlayer * @param name The name of the new UIlayer
*/ */
addUILayer(name: string): UILayer { addUILayer(name: string): UILayer {
if(this.layers.has(name) || this.uiLayers.has(name)){ if(this.layers.has(name) || this.parallaxLayers.has(name) || this.uiLayers.has(name)){
throw `Layer with name ${name} already exists`; throw `Layer with name ${name} already exists`;
} }

View File

@ -82,7 +82,7 @@ export default class MathUtils {
factor *= 16; factor *= 16;
} }
let hexStr = ""; let hexStr = "";
while(num > 0){ while(factor >= 1){
let digit = Math.floor(num/factor); let digit = Math.floor(num/factor);
hexStr += MathUtils.toHexDigit(digit); hexStr += MathUtils.toHexDigit(digit);
num -= digit * factor; num -= digit * factor;

View File

@ -31,6 +31,7 @@ export default class GoombaController extends StateMachineAI {
this.receiver.subscribe("playerHitCoinBlock"); this.receiver.subscribe("playerHitCoinBlock");
if(this.jumpy){ if(this.jumpy){
this.receiver.subscribe(CustomGameEventType.PLAYER_JUMP); this.receiver.subscribe(CustomGameEventType.PLAYER_JUMP);
this.speed = 100;
} }
let idle = new Idle(this, owner); let idle = new Idle(this, owner);

View File

@ -6,7 +6,7 @@ import GoombaController, { GoombaStates } from "./GoombaController";
export default abstract class GoombaState extends State { export default abstract class GoombaState extends State {
owner: GameNode; owner: GameNode;
gravity: number = 7000; gravity: number = 1000;
parent: GoombaController parent: GoombaController
constructor(parent: StateMachine, owner: GameNode){ constructor(parent: StateMachine, owner: GameNode){

View File

@ -1,5 +1,6 @@
import Vec2 from "../../DataTypes/Vec2"; import Vec2 from "../../DataTypes/Vec2";
import GameEvent from "../../Events/GameEvent"; import GameEvent from "../../Events/GameEvent";
import AnimatedSprite from "../../Nodes/Sprites/AnimatedSprite";
import { CustomGameEventType } from "../CustomGameEventType"; import { CustomGameEventType } from "../CustomGameEventType";
import { GoombaStates } from "./GoombaController"; import { GoombaStates } from "./GoombaController";
import OnGround from "./OnGround"; import OnGround from "./OnGround";
@ -7,6 +8,11 @@ import OnGround from "./OnGround";
export default class Idle extends OnGround { export default class Idle extends OnGround {
onEnter(): void { onEnter(): void {
this.parent.speed = this.parent.speed; this.parent.speed = this.parent.speed;
(<AnimatedSprite>this.owner).animation.play("IDLE", true);
}
onExit(): void {
(<AnimatedSprite>this.owner).animation.stop();
} }
handleInput(event: GameEvent) { handleInput(event: GameEvent) {

View File

@ -1,10 +1,15 @@
import GameEvent from "../../Events/GameEvent"; import GameEvent from "../../Events/GameEvent";
import AnimatedSprite from "../../Nodes/Sprites/AnimatedSprite";
import { GoombaStates } from "./GoombaController"; import { GoombaStates } from "./GoombaController";
import GoombaState from "./GoombaState"; import GoombaState from "./GoombaState";
export default class Jump extends GoombaState { export default class Jump extends GoombaState {
onEnter(): void {} onEnter(): void {
(<AnimatedSprite>this.owner).animation.play("JUMP", true);
(<AnimatedSprite>this.owner).tweens.play("jump", true);
this.gravity = 500;
}
update(deltaT: number): void { update(deltaT: number): void {
super.update(deltaT); super.update(deltaT);
@ -22,5 +27,8 @@ export default class Jump extends GoombaState {
this.owner.move(this.parent.velocity.scaled(deltaT)); this.owner.move(this.parent.velocity.scaled(deltaT));
} }
onExit(): void {} onExit(): void {
(<AnimatedSprite>this.owner).animation.stop();
(<AnimatedSprite>this.owner).tweens.stop("jump");
}
} }

View File

@ -1,4 +1,5 @@
import Vec2 from "../../DataTypes/Vec2"; import Vec2 from "../../DataTypes/Vec2";
import AnimatedSprite from "../../Nodes/Sprites/AnimatedSprite";
import { GoombaStates } from "./GoombaController"; import { GoombaStates } from "./GoombaController";
import OnGround from "./OnGround"; import OnGround from "./OnGround";
@ -8,8 +9,11 @@ export default class Walk extends OnGround {
onEnter(): void { onEnter(): void {
if(this.parent.direction.isZero()){ if(this.parent.direction.isZero()){
this.parent.direction = new Vec2(-1, 0); this.parent.direction = new Vec2(-1, 0);
(<AnimatedSprite>this.owner).invertX = true;
} }
(<AnimatedSprite>this.owner).animation.play("WALK", true);
this.time = Date.now(); this.time = Date.now();
} }
@ -19,16 +23,22 @@ export default class Walk extends OnGround {
if(this.owner.onWall){ if(this.owner.onWall){
// Flip around // Flip around
this.parent.direction.x *= -1; this.parent.direction.x *= -1;
(<AnimatedSprite>this.owner).invertX = !(<AnimatedSprite>this.owner).invertX;
} }
if(this.parent.jumpy && (Date.now() - this.time > 500)){ if(this.parent.jumpy && (Date.now() - this.time > 500)){
console.log("Jump"); console.log("Jump");
this.finished(GoombaStates.JUMP); this.finished(GoombaStates.JUMP);
this.parent.velocity.y = -2000; this.parent.velocity.y = -300;
} }
this.parent.velocity.x = this.parent.direction.x * this.parent.speed; this.parent.velocity.x = this.parent.direction.x * this.parent.speed;
this.owner.move(this.parent.velocity.scaled(deltaT)); this.owner.move(this.parent.velocity.scaled(deltaT));
} }
onExit(): void {
(<AnimatedSprite>this.owner).animation.stop();
}
} }

View File

@ -11,6 +11,7 @@ import OrthogonalTilemap from "../../Nodes/Tilemaps/OrthogonalTilemap";
import AnimatedSprite from "../../Nodes/Sprites/AnimatedSprite"; import AnimatedSprite from "../../Nodes/Sprites/AnimatedSprite";
import Debug from "../../Debug/Debug"; import Debug from "../../Debug/Debug";
import { EaseFunctionType } from "../../Utils/EaseFunctions"; import { EaseFunctionType } from "../../Utils/EaseFunctions";
import Sprite from "../../Nodes/Sprites/Sprite";
export enum MarioEvents { export enum MarioEvents {
PLAYER_HIT_COIN = "PlayerHitCoin", PLAYER_HIT_COIN = "PlayerHitCoin",
@ -23,20 +24,34 @@ export default class Level1 extends Scene {
coinCountLabel: Label; coinCountLabel: Label;
livesCount: number = 3; livesCount: number = 3;
livesCountLabel: Label; livesCountLabel: Label;
bg: Sprite;
loadScene(): void { loadScene(): void {
this.load.image("background", "/assets/sprites/2bitbackground.png");
this.load.image("coin", "/assets/sprites/coin.png");
this.load.tilemap("level1", "/assets/tilemaps/2bitlevel1.json"); this.load.tilemap("level1", "/assets/tilemaps/2bitlevel1.json");
this.load.image("goomba", "assets/sprites/Goomba.png");
this.load.image("koopa", "assets/sprites/Koopa.png");
this.load.spritesheet("player", "assets/spritesheets/walking.json"); this.load.spritesheet("player", "assets/spritesheets/walking.json");
this.load.spritesheet("hopper", "assets/spritesheets/hopper.json");
this.load.spritesheet("bunny", "assets/spritesheets/ghostBunny.json");
} }
startScene(): void { startScene(): void {
// Add a background layer and set the background image on it
this.addParallaxLayer("bg", new Vec2(0.25, 0), -100);
let bg = this.add.sprite("background", "bg");
bg.scale.set(2, 2);
bg.position.set(bg.boundary.halfSize.x, 16);
this.bg = bg;
this.bg.toString = () => "BackgroundImage";
let tilemap = <OrthogonalTilemap>this.add.tilemap("level1", new Vec2(2, 2))[0].getItems()[0]; let tilemap = <OrthogonalTilemap>this.add.tilemap("level1", new Vec2(2, 2))[0].getItems()[0];
//tilemap.position.set(tilemap.size.x*tilemap.scale.x/2, tilemap.size.y*tilemap.scale.y/2); //tilemap.position.set(tilemap.size.x*tilemap.scale.x/2, tilemap.size.y*tilemap.scale.y/2);
tilemap.position.set(0, 0); tilemap.position.set(0, 0);
this.viewport.setBounds(0, 0, 128*32, 20*32); this.viewport.setBounds(0, 0, 128*32, 20*32);
// Add a layer behind the tilemap for coin animation
this.addLayer("coinLayer", -50);
// Add the player (a rect for now) // Add the player (a rect for now)
// this.player = this.add.graphic(GraphicType.RECT, "Main", {position: new Vec2(192, 1152), size: new Vec2(64, 64)}); // this.player = this.add.graphic(GraphicType.RECT, "Main", {position: new Vec2(192, 1152), size: new Vec2(64, 64)});
this.player = this.add.animatedSprite("player", "Main"); this.player = this.add.animatedSprite("player", "Main");
@ -70,23 +85,37 @@ export default class Level1 extends Scene {
this.viewport.setZoomLevel(2); this.viewport.setZoomLevel(2);
// Add enemies // Add enemies
// for(let pos of [{x: 21, y: 18}, {x: 30, y: 18}, {x: 37, y: 18}, {x: 41, y: 18}, {x: 105, y: 8}, {x: 107, y: 8}, {x: 125, y: 18}]){ for(let pos of [{x: 21, y: 18}]){//, {x: 30, y: 18}, {x: 37, y: 18}, {x: 41, y: 18}, {x: 105, y: 8}, {x: 107, y: 8}, {x: 125, y: 18}]){
// let goomba = this.add.sprite("goomba", "Main"); let bunny = this.add.animatedSprite("bunny", "Main");
// goomba.position.set(pos.x*64, pos.y*64); bunny.position.set(pos.x*32, pos.y*32);
// goomba.scale.set(2, 2); bunny.scale.set(2, 2);
// goomba.addPhysics(); bunny.addPhysics();
// goomba.addAI(GoombaController, {jumpy: false}); bunny.addAI(GoombaController, {jumpy: false});
// goomba.setPhysicsLayer("enemy"); bunny.setPhysicsLayer("enemy");
// } }
// for(let pos of [{x: 67, y: 18}, {x: 86, y: 21}, {x: 128, y: 18}]){ for(let pos of [{x: 67, y: 18}]){//, {x: 86, y: 21}, {x: 128, y: 18}]){
// let koopa = this.add.sprite("koopa", "Main"); let hopper = this.add.animatedSprite("hopper", "Main");
// koopa.position.set(pos.x*64, pos.y*64); hopper.position.set(pos.x*32, pos.y*32);
// koopa.scale.set(2, 2); hopper.scale.set(2, 2);
// koopa.addPhysics(); hopper.addPhysics();
// koopa.addAI(GoombaController, {jumpy: true}); hopper.addAI(GoombaController, {jumpy: true});
// koopa.setPhysicsLayer("enemy"); hopper.setPhysicsLayer("enemy");
// } hopper.tweens.add("jump", {
startDelay: 0,
duration: 300,
effects: [
{
property: "rotation",
resetOnComplete: true,
start: -3.14/8,
end: 3.14/8,
ease: EaseFunctionType.IN_OUT_SINE
}
],
reverseOnComplete: true,
});
}
// Add UI // Add UI
this.addUILayer("UI"); this.addUILayer("UI");
@ -96,6 +125,8 @@ export default class Level1 extends Scene {
} }
updateScene(deltaT: number): void { updateScene(deltaT: number): void {
Debug.log("pos", this.bg.position);
while(this.receiver.hasNextEvent()){ while(this.receiver.hasNextEvent()){
let event = this.receiver.getNextEvent(); let event = this.receiver.getNextEvent();

View File

@ -2,7 +2,9 @@ import StateMachineAI from "../../AI/StateMachineAI";
import Vec2 from "../../DataTypes/Vec2"; import Vec2 from "../../DataTypes/Vec2";
import Debug from "../../Debug/Debug"; import Debug from "../../Debug/Debug";
import GameNode from "../../Nodes/GameNode"; import GameNode from "../../Nodes/GameNode";
import Sprite from "../../Nodes/Sprites/Sprite";
import OrthogonalTilemap from "../../Nodes/Tilemaps/OrthogonalTilemap"; import OrthogonalTilemap from "../../Nodes/Tilemaps/OrthogonalTilemap";
import { TweenData } from "../../Rendering/Animations/AnimationTypes";
import IdleTopDown from "./PlayerStates/IdleTopDown"; import IdleTopDown from "./PlayerStates/IdleTopDown";
import MoveTopDown from "./PlayerStates/MoveTopDown"; import MoveTopDown from "./PlayerStates/MoveTopDown";
import Idle from "./PlayerStates/Platformer/Idle"; import Idle from "./PlayerStates/Platformer/Idle";
@ -29,8 +31,9 @@ export default class PlayerController extends StateMachineAI {
velocity: Vec2 = Vec2.ZERO; velocity: Vec2 = Vec2.ZERO;
speed: number = 200; speed: number = 200;
MIN_SPEED: number = 200; MIN_SPEED: number = 200;
MAX_SPEED: number = 500; MAX_SPEED: number = 300;
tilemap: OrthogonalTilemap; tilemap: OrthogonalTilemap;
coin: Sprite;
initializeAI(owner: GameNode, options: Record<string, any>){ initializeAI(owner: GameNode, options: Record<string, any>){
this.owner = owner; this.owner = owner;
@ -42,6 +45,8 @@ export default class PlayerController extends StateMachineAI {
} }
this.tilemap = this.owner.getScene().getTilemap(options.tilemap) as OrthogonalTilemap; this.tilemap = this.owner.getScene().getTilemap(options.tilemap) as OrthogonalTilemap;
this.coin = this.owner.getScene().add.sprite("coin", "coinLayer");
this.coin.scale.set(2, 2);
} }
/** /**

View File

@ -1,6 +1,7 @@
import Vec2 from "../../../../DataTypes/Vec2"; import Vec2 from "../../../../DataTypes/Vec2";
import GameEvent from "../../../../Events/GameEvent"; import GameEvent from "../../../../Events/GameEvent";
import AnimatedSprite from "../../../../Nodes/Sprites/AnimatedSprite"; import AnimatedSprite from "../../../../Nodes/Sprites/AnimatedSprite";
import { EaseFunctionType } from "../../../../Utils/EaseFunctions";
import MathUtils from "../../../../Utils/MathUtils"; import MathUtils from "../../../../Utils/MathUtils";
import { CustomGameEventType } from "../../../CustomGameEventType"; import { CustomGameEventType } from "../../../CustomGameEventType";
import Level1, { MarioEvents } from "../../../Mario/Level1"; import Level1, { MarioEvents } from "../../../Mario/Level1";
@ -28,12 +29,35 @@ export default class Jump extends PlayerState {
pos = this.parent.tilemap.getColRowAt(pos); pos = this.parent.tilemap.getColRowAt(pos);
let tile = this.parent.tilemap.getTileAtRowCol(pos); let tile = this.parent.tilemap.getTileAtRowCol(pos);
console.log("Hit tile: " + tile);
// If coin block, change to empty coin block // If coin block, change to empty coin block
if(tile === 17){ if(tile === 17){
this.parent.tilemap.setTileAtRowCol(pos, 18); this.parent.tilemap.setTileAtRowCol(pos, 18);
this.emitter.fireEvent(MarioEvents.PLAYER_HIT_COIN_BLOCK); this.emitter.fireEvent(MarioEvents.PLAYER_HIT_COIN_BLOCK);
let tileSize = this.parent.tilemap.getTileSize();
this.parent.coin.position.copy(pos.scale(tileSize.x, tileSize.y).add(tileSize.scaled(0.5)));
// Animate collision
this.parent.coin.tweens.add("coin", {
startDelay: 0,
duration: 300,
effects: [{
property: "positionY",
resetOnComplete: false,
start: this.parent.coin.position.y,
end: this.parent.coin.position.y - 2*tileSize.y,
ease: EaseFunctionType.OUT_SINE
},
{
property: "alpha",
resetOnComplete: false,
start: 1,
end: 0,
ease: EaseFunctionType.OUT_SINE
}]
});
this.parent.coin.tweens.play("coin");
} }
} }

View File

@ -20,7 +20,7 @@ export default class PlayerController extends StateMachineAI {
velocity: Vec2 = Vec2.ZERO; velocity: Vec2 = Vec2.ZERO;
speed: number = 400; speed: number = 400;
MIN_SPEED: number = 400; MIN_SPEED: number = 400;
MAX_SPEED: number = 1000; MAX_SPEED: number = 400;
initializeAI(owner: GameNode, config: Record<string, any>): void { initializeAI(owner: GameNode, config: Record<string, any>): void {
this.owner = owner; this.owner = owner;

View File

@ -7,7 +7,7 @@ export default class Walk extends OnGround {
owner: AnimatedSprite; owner: AnimatedSprite;
onEnter(): void { onEnter(): void {
this.parent.speed = this.parent.MAX_SPEED/2; this.parent.speed = this.parent.MIN_SPEED;
this.owner.animation.play("WALK", true); this.owner.animation.play("WALK", true);
} }