Commit 67e21abf authored by haiyoucuv's avatar haiyoucuv

蛇移动

parent d88315b3
src/assets/GamePage/bg.jpg

136 KB | W: | H:

src/assets/GamePage/bg.jpg

136 KB | W: | H:

src/assets/GamePage/bg.jpg
src/assets/GamePage/bg.jpg
src/assets/GamePage/bg.jpg
src/assets/GamePage/bg.jpg
  • 2-up
  • Swipe
  • Onion skin
......@@ -8,7 +8,7 @@ export class Joystick extends Container {
handle: Sprite = null;
dir: Point = new Point();
dir: Point = new Point(1, 0);
constructor() {
super();
......@@ -51,8 +51,9 @@ export class Joystick extends Container {
this.calcDir(e.data.global.x, e.data.global.y);
}
const handlePointerUp = () => {
this.calcDir(this.x, this.y);
const handlePointerUp = (e) => {
this.calcDir(e.data.global.x, e.data.global.y);
this.handle.position.set(0, 0);
getApp().stage.off("pointermove", handlePointerMove);
getApp().stage.off("pointerup", handlePointerUp);
}
......
import { Assets, Container, Point, PointData, Sprite } from "pixi.js";
import { mapTop, winSize } from "@/pages/GamePage/Game.ts";
export class Snake extends Container {
head: Sprite = null;
bodyArr: Sprite[] = [];
protected _bodyScale: number = 1;
get bodyScale() {
return this._bodyScale;
}
set bodyScale(value: number) {
this._bodyScale = value;
}
_energy: number = 0;
get energy() {
return this._energy;
}
set energy(value: number) {
this._energy = value;
}
private _length: number = 0;
get length() {
return this._length;
}
set length(value: number) {
this._length = value;
this.emit("updateLength", value);
}
get radius() {
return this.bodyScale * 46 / 2;
}
// 位置相关
private ready: boolean = false;
isLife: boolean = true;
speed: number = 166;
dir: Point = new Point(1, 0);
constructor() {
super();
this.initUI();
}
initUI() {
this.ready = false;
this.bodyArr.forEach((body) => {
body.removeFromParent();
});
this.energy = 0;
this.scale = 1;
this.bodyArr.length = 0;
// 设置头部
this.head = this.addChild(new Sprite(Assets.get("蛇/初级/head.png")));
this.head.angle = 0;
this.head.position.set(375, 375);
this.head.anchor.set(0.5, 0.5);
this.length = 1;
// 创建身体节点
this.addEnergy(50);
this.isLife = true;
this.ready = true;
}
onEnable() {
}
onDisable() {
}
// 上次生长富余的能量
private lastRemaining = 0;
/**
* 加能量
* 暂定加长/双倍道具卡效果不叠加
*/
addEnergy(value: number, useProps: boolean = false) {
this.energy += value
const growthThreshold = Math.floor(12 * this.bodyScale);
value += this.lastRemaining;
while (value >= growthThreshold) {
value -= growthThreshold;
if (this.bodyScale < 3) {
this.bodyScale += 0.01;
}
this.grow();
}
this.lastRemaining = value;
// this.speed = 600 * this.scale;
}
/**
* 快速生长
*/
fastGrow(energy: number) {
this.addEnergy(energy)
// for (let i = 0; i < time; i++) {
// this.grow();
// }
}
/**
* 生长
*/
private grow() {
if (this.length > 180) {
return;
}
if (!this.isLife) return;
this.length += 1;
let len = this.bodyArr.length;
const newBody = new Sprite(Assets.get("蛇/初级/body0.png"));
const pre = this.bodyArr[len - 1] || this.head;
newBody.angle = pre.angle;
newBody.position.set(999999, 999999);
newBody.scale.set(this.bodyScale, this.bodyScale);
this.addChildAt(newBody, 0);
newBody.anchor.set(0.5, 0.5);
// newBody.active = isIntersect(
// newBody.getPosition(),
// this.head.getPosition(),
// this.vw,
// this.vh
// );
this.bodyArr.splice(len, 0, newBody);
}
positions: PointData[] = []; // 存储历史位置点
private readonly HISTORY_LENGTH = 10; // 增加历史点数量
private readonly SEGMENT_SPACING = 6.3; // 增加节点间距
moveTime = 1 / 60;
totalTime = 0;
onUpdate(dt: number) {
this.totalTime += dt;
while (this.totalTime >= this.moveTime) {
this.totalTime -= this.moveTime;
this.move(this.moveTime);
}
}
protected move(dt: number) {
if (!this.ready || !this.isLife) {
return;
}
const bodyLen = this.bodyArr.length;
const headAngle = this.head.angle = Math.atan2(this.dir.y, this.dir.x) * 180 / Math.PI;
// 更新头部位置
const newHeadPos = this.dir
.multiplyScalar(dt * this.speed)
.add(this.head.position);
if (newHeadPos.x < -10) newHeadPos.x = 750 + 10;
if (newHeadPos.x > 750 + 10) newHeadPos.x = -10;
if (newHeadPos.y < -10) newHeadPos.y = winSize.height - mapTop + 10;
if (newHeadPos.y > winSize.height - mapTop + 10) newHeadPos.y = -10;
this.head.position.set(newHeadPos.x, newHeadPos.y);
const flipY = headAngle > 90 && headAngle < 270;
this.head.scale.set(this.bodyScale, flipY ? -this.bodyScale : this.bodyScale);
const space = this.SEGMENT_SPACING * this.bodyScale;
// 存储历史位置
this.positions.unshift(newHeadPos);
// 确保历史位置点足够多,以容纳所有身体节点
const requiredLength = this.bodyArr.length * space + 1;
if (this.positions.length > requiredLength) {
this.positions.pop();
}
// 更新身体节点位置
for (let i = 0; i < bodyLen; i++) {
const body = this.bodyArr[i];
// 为每个节点计算一个固定的偏移量
const offset = (i + 1) * (~~space);
// 确保不会超出历史位置数组范围
if (offset < this.positions.length) {
const targetPos = this.positions[offset];
// 计算角度
if (offset > 0) {
const prevPos = this.positions[offset - 1];
body.angle = Math.atan2(
targetPos.y - prevPos.y,
targetPos.x - prevPos.x
) * 180 / Math.PI;
}
body.position.set(targetPos.x, targetPos.y);
body.scale.set(this.bodyScale, this.bodyScale);
}
}
// // 边界检查
// const mapHalfWidth = Global.HALF_MAP_WIDTH;
// const mapHalfHeight = Global.HALF_MAP_HEIGHT;
// if (
// newHeadPos.x < -mapHalfWidth
// || newHeadPos.x > mapHalfWidth
// || newHeadPos.y < -mapHalfHeight
// || newHeadPos.y > mapHalfHeight
// ) {
// this.death();
// }
}
/****************************** 磁铁 ******************************/
useMagnet() {
this.clearMagnet();
// this.magnetEffectNode.active = true;
// this.magnetEffectNode.getComponent(Animation).play();
// this.eatCollider.radius = Global.PROP_MAGNET_RADIUS;
// this.scheduleOnce(this.clearMagnet, Global.PROP_MAGNET_DUR_TIME)
}
clearMagnet() {
// this.unschedule(this.clearMagnet)
// this.magnetEffectNode.active = false;
// this.magnetEffectNode.getComponent(Animation).stop();
// this.eatCollider.radius = 65;
}
}
......@@ -2,10 +2,21 @@ import { Assets, Container, Sprite, Ticker } from "pixi.js";
import bgImg from "@/assets/GamePage/bg.jpg";
import { Joystick } from "@/pages/GamePage/Components/Joystick.ts";
import 'pixi.js/math-extras';
import { Snake } from "@/pages/GamePage/Components/Snake.ts";
export const winSize = {
width: 750,
height: window.innerHeight / window.innerWidth * 750,
}
export const mapTop = 290;
export class Game extends Container {
joystick: Joystick = null;
private snake: Snake;
private mapCtn: Container;
constructor() {
super();
......@@ -17,10 +28,16 @@ export class Game extends Container {
const bg = this.addChild(new Sprite());
Assets.load(bgImg).then((texture) => bg.texture = texture);
this.joystick = this.addChild(new Joystick());
this.joystick.visible = false;
this.mapCtn = this.addChild(new Container());
this.mapCtn.y = mapTop;
this.snake = this.mapCtn.addChild(new Snake());
this.on("pointerdown", this.onPointerDown, this);
this.on("pointerup", this.onPointerUp, this);
......@@ -38,6 +55,8 @@ export class Game extends Container {
}
onUpdate(time: Ticker) {
// 更新游戏逻辑
const dt = time.deltaMS / 1000;
this.snake.dir.copyFrom(this.joystick.dir);
this.snake.onUpdate(dt);
}
}
......@@ -3,10 +3,9 @@
.GamePage {
position: absolute;
left: 0;
top: 50%;
width: 750px;
height: 1624px;
transform: translateY(-50%);
top: 0;
width: 100%;
height: 100%;
.gameBg {
position: absolute;
......@@ -22,14 +21,14 @@
position: absolute;
left: 0;
top: 0;
width: 750px;
height: 1624px;
width: 100%;
height: 100%;
}
.musicBtn {
position: absolute;
left: 678px;
top: 279px;
top: 130px;
width: 46px;
height: 46px;
}
......@@ -37,7 +36,7 @@
.scoreArea {
position: absolute;
left: 236px;
top: 214px;
top: 48px;
width: 277px;
height: 79px;
.webpBg("GamePage/我的分数.png");
......@@ -46,7 +45,7 @@
.backBtn {
position: absolute;
left: 17px;
top: 216px;
top: 50px;
width: 74px;
height: 76px;
.webpBg("GamePage/返回.png");
......
......@@ -9,7 +9,7 @@ import { Tween } from "./tween";
import { initBundle } from "@/pages/GamePage/Helper.ts";
import MusicBtn from "@/core/components/MusicBtn/MusicBtn.tsx";
import { PageCtrl } from "@/core/ctrls/PageCtrl.tsx";
import { Game } from "@/pages/GamePage/Game.ts";
import { Game, winSize } from "@/pages/GamePage/Game.ts";
export function getApp(): Application {
return window["__app"];
......@@ -50,8 +50,9 @@ class GamePage extends React.Component {
await app.init({
canvas: this.gameCanvas,
backgroundColor: 0xffffff,
width: 750,
height: 1624,
width: winSize.width,
height: winSize.height,
powerPreference: "high-performance",
// resolution: Math.min(window.devicePixelRatio, 2) || 1,
resolution: 1,
preference: "webgl",
......
......@@ -4,7 +4,6 @@ import './HomePage.less';
import {Button} from "@grace/ui";
import {_asyncThrottle} from "@/utils/utils.ts";
import store from "@/store/store.ts";
import {PAGE_MAP} from "@/utils/constants.ts";
import {SvgaPlayer} from "@grace/svgaplayer";
import homeSvga from "@/assets/svga/1输出首页氛围.svga";
import gameStore from "@/store/gameStore.ts";
......
import React from "react";
import { observer } from "mobx-react";
import { PAGE_MAP } from "@/utils/constants.ts";
import store from "../../store/store";
import { preload } from "@/core/preload.ts";
import "./LoadingDemo.less";
import { PageCtrl } from "@/core/ctrls/PageCtrl.tsx";
......
......@@ -2,8 +2,6 @@ import React from 'react';
import {observer} from 'mobx-react';
import './MyPrize.less';
import {Button} from "@grace/ui";
import store from "@/store/store.ts";
import {PAGE_MAP} from "@/utils/constants.ts";
import {dateFormatter} from "@/utils/utils.ts";
import API from "@/api";
import { PageCtrl } from "@/core/ctrls/PageCtrl.tsx";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment