|
@@ -1,511 +1,837 @@
|
|
|
<template>
|
|
|
- <div id="main_box">
|
|
|
- <canvas ref="can1" id="myCanvas1" class="can"></canvas>
|
|
|
- <canvas ref="can2" id="myCanvas2" class="can"></canvas>
|
|
|
- <button id="login_btn" @click="loginGame" v-if="!beginGame && !gameOver">开始游戏</button>
|
|
|
- <div id="score" v-if="beginGame && !gameOver">得分: {{ Math.floor(score) }}</div>
|
|
|
- <div id="game_title" v-if="!beginGame && !gameOver">方 块 跳 跃</div>
|
|
|
- <div id="state" v-if="gameOver">游戏结束,得分:{{ Math.floor(score) }}</div>
|
|
|
- <span
|
|
|
- id="square_main"
|
|
|
- v-if="mySquare && mySquare.isLive"
|
|
|
- :style="{ left: mySquare.x + 'px', top: mySquare.y + 'px', background: mySquare.color }"
|
|
|
- ></span>
|
|
|
- <div id="colorChangeTime_div" v-if="showColorChange">{{ changeTimeArrays[changeColorIndex] }}</div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
-
|
|
|
- <script setup lang="ts">
|
|
|
- import { ref, onMounted, onBeforeUnmount } from 'vue';
|
|
|
-
|
|
|
- interface BackgroundObj {
|
|
|
- x: number[];
|
|
|
- y: number[];
|
|
|
- w: number[];
|
|
|
- h: number[];
|
|
|
- isLive: boolean[];
|
|
|
- num: number;
|
|
|
- init: () => void;
|
|
|
- draw: () => void;
|
|
|
- cloudBorn: () => void;
|
|
|
+ <div id="main_box" ref="main_box">
|
|
|
+ <canvas id="myCanvas1" class="can" ref="can1"></canvas>
|
|
|
+ <canvas id="myCanvas2" class="can" ref="can2"></canvas>
|
|
|
+ <a href="javascript:void(0)" @click="loginGame" id="login_btn" ref="login_btn">开始游戏</a>
|
|
|
+ <div id="score" ref="score_div">{{ scoreText }}</div>
|
|
|
+ <div id="game_title" ref="game_title">方 块 跳 跃</div>
|
|
|
+ <div id="state" ref="state_div">{{ stateText }}</div>
|
|
|
+ <span id="square_main" ref="square_main"></span>
|
|
|
+ <div id="colorChangeTime_div" ref="colorChangeTime_div">{{ colorChangeTimeText }}</div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { ref, onMounted, onBeforeUnmount } from 'vue';
|
|
|
+const changeTimeArrays: any = ["10", "9", "8", "7", "6", "5", "4", "3", "2", "1", "color change!"];
|
|
|
+const squareColor: any = ["#FF6688", "#00FF00", "#3399FF", "#FFDAB9", "blueviolet"];
|
|
|
+
|
|
|
+const can1: any = ref(null);
|
|
|
+const can2: any = ref(null);
|
|
|
+const ctx1: any = ref(null);
|
|
|
+const ctx2: any = ref(null);
|
|
|
+const canWidth: any = ref(820);
|
|
|
+const canHeight: any = ref(640);
|
|
|
+const maxWidth: any = ref(820);
|
|
|
+const maxHeight: any = ref(640);
|
|
|
+const beginGame: any = ref(false);
|
|
|
+const gameOver: any = ref(true);
|
|
|
+const score: any = ref(0);
|
|
|
+const scoreText: any = ref('得分:0');
|
|
|
+const stateText: any = ref('');
|
|
|
+const colorChangeTimeText: any = ref();
|
|
|
+let backrgound: any = ref(null);
|
|
|
+let squares: any = ref(null);
|
|
|
+let mySquare: any = ref(null);
|
|
|
+let beginAnim: any = ref(null);
|
|
|
+let lastTime: any = ref(null);
|
|
|
+let changeColorTime: any = ref(null);
|
|
|
+let loop: any = ref(null);
|
|
|
+
|
|
|
+const changeColorindex: any = ref(0);
|
|
|
+const totalSpeed: any = ref(3);
|
|
|
+const isStep: any = ref(false);
|
|
|
+const colorChangeTimeW: any = ref(0);
|
|
|
+const AnimPX: any = ref([]);
|
|
|
+const AnimPY: any = ref([]);
|
|
|
+const jump_count: any = ref(0);
|
|
|
+let square_main: any = ref(null);
|
|
|
+let game_title: any = ref(null);
|
|
|
+let main_box: any = ref(null);
|
|
|
+let login_btn: any = ref(null);
|
|
|
+let colorChangeTime_div: any = ref(null);
|
|
|
+let state_div: any = ref(null);
|
|
|
+let score_div: any = ref(null);
|
|
|
+
|
|
|
+function init() {
|
|
|
+ score.value = 0;
|
|
|
+ beginGame.value = false;
|
|
|
+ gameOver.value = false;
|
|
|
+ isStep.value = false;
|
|
|
+
|
|
|
+ lastTime.value = Date.now();
|
|
|
+ ctx1.value = can1.value.getContext("2d");
|
|
|
+ ctx2.value = can2.value.getContext("2d");
|
|
|
+ if (maxWidth.value != canWidth.value) {
|
|
|
+ canWidth.value = maxWidth.value;
|
|
|
}
|
|
|
-
|
|
|
- interface SquareObj {
|
|
|
- x: number[];
|
|
|
- y: number[];
|
|
|
- w: number[];
|
|
|
- h: number[];
|
|
|
- color: string[];
|
|
|
- isLive: boolean[];
|
|
|
- num: number;
|
|
|
- init: () => void;
|
|
|
- draw: () => void;
|
|
|
- squareBorn: () => void;
|
|
|
+ if (maxHeight.value != canHeight.value) {
|
|
|
+ canHeight.value = maxHeight.value;
|
|
|
}
|
|
|
-
|
|
|
- interface MySquareObj {
|
|
|
- x: number;
|
|
|
- y: number;
|
|
|
- isLive: boolean;
|
|
|
- l: number;
|
|
|
- color: string;
|
|
|
- toDownSpeed: number;
|
|
|
- toVSpeed: number;
|
|
|
- init: () => void;
|
|
|
- jump: () => void;
|
|
|
- toDown: () => void;
|
|
|
- draw: () => void;
|
|
|
+
|
|
|
+
|
|
|
+ main_box.value.style.width = canWidth.value + "px";
|
|
|
+ main_box.value.style.height = canHeight.value + "px";
|
|
|
+
|
|
|
+ can1.value.width = canWidth.value;
|
|
|
+ can2.value.width = canWidth.value;
|
|
|
+ can1.value.height = canHeight.value;
|
|
|
+ can2.value.height = canHeight.value;
|
|
|
+
|
|
|
+ // 模拟 slideDown 效果
|
|
|
+ game_title.value.style.display = "block";
|
|
|
+ game_title.value.style.height = "0";
|
|
|
+ game_title.value.style.overflow = "hidden";
|
|
|
+ setTimeout(() => {
|
|
|
+ game_title.value.style.height = "auto";
|
|
|
+ }, 0);
|
|
|
+
|
|
|
+ // 模拟 delay 和 slideToggle 效果
|
|
|
+ setTimeout(() => {
|
|
|
+ login_btn.value.style.display = "block";
|
|
|
+ login_btn.value.style.height = "0";
|
|
|
+ login_btn.value.style.overflow = "hidden";
|
|
|
+ setTimeout(() => {
|
|
|
+ login_btn.value.style.height = "auto";
|
|
|
+ }, 10);
|
|
|
+ }, 500);
|
|
|
+
|
|
|
+ colorChangeTimeW.value = (canHeight.value > canWidth.value ? canWidth.value : canHeight.value) * 0.5;
|
|
|
+ colorChangeTime_div.value.style.width = colorChangeTimeW * 1.6 + "px";
|
|
|
+ colorChangeTime_div.value.style.height = colorChangeTimeW * 0.5 + "px";
|
|
|
+ colorChangeTime_div.value.style.marginLeft = -colorChangeTimeW * 0.8 + "px";
|
|
|
+ colorChangeTime_div.value.style.lineHeight = colorChangeTimeW * 0.5 + "px";
|
|
|
+ colorChangeTime_div.value.style.fontSize = colorChangeTimeW * 0.3 + "px";
|
|
|
+
|
|
|
+ backrgound.value = new backgroundObj();
|
|
|
+ backrgound.value.init();
|
|
|
+
|
|
|
+ squares.value = new squareObj();
|
|
|
+ squares.value.init();
|
|
|
+
|
|
|
+ mySquare.value = new mySquareObj();
|
|
|
+ mySquare.value.init();
|
|
|
+
|
|
|
+ beginAnim.value = new beginAnimObj();
|
|
|
+ beginAnim.value.init();
|
|
|
+}
|
|
|
+
|
|
|
+function restartInit() {
|
|
|
+ AnimPX.value = new Array();
|
|
|
+ AnimPY.value = new Array();
|
|
|
+ changeColorindex.value = 0;
|
|
|
+ jump_count.value = 0;
|
|
|
+
|
|
|
+ // 隐藏元素
|
|
|
+ colorChangeTime_div.value.style.display = "none";
|
|
|
+ score_div.value.style.display = "none";
|
|
|
+
|
|
|
+ // 初始化动画
|
|
|
+ beginAnim.value.init();
|
|
|
+
|
|
|
+ // 设置游戏状态
|
|
|
+ beginGame.value = false;
|
|
|
+ gameOver.value = true;
|
|
|
+ lastTime.value = Date.now();
|
|
|
+
|
|
|
+ // 设置游戏标题
|
|
|
+ game_title.value.innerHTML = "方 块 跳 跃";
|
|
|
+
|
|
|
+ // 显示游戏标题(模拟slideDown效果)
|
|
|
+ game_title.value.style.display = "block";
|
|
|
+ game_title.value.style.height = "0";
|
|
|
+ game_title.value.style.overflow = "hidden";
|
|
|
+ setTimeout(() => {
|
|
|
+ game_title.value.style.height = "auto";
|
|
|
+ }, 0);
|
|
|
+
|
|
|
+ // 延迟显示登录按钮(模拟delay和slideToggle效果)
|
|
|
+ setTimeout(() => {
|
|
|
+ login_btn.value.style.display = "block";
|
|
|
+ login_btn.value.style.height = "0";
|
|
|
+ login_btn.value.style.overflow = "hidden";
|
|
|
+ setTimeout(() => {
|
|
|
+ login_btn.value.style.height = "auto";
|
|
|
+ }, 10);
|
|
|
+ }, 500);
|
|
|
+
|
|
|
+ // 设置登录按钮文本
|
|
|
+ login_btn.value.innerHTML = "再来一次";
|
|
|
+
|
|
|
+ // 显示状态(模拟slideDown效果)
|
|
|
+ state_div.value.style.display = "block";
|
|
|
+ state_div.value.style.height = "0";
|
|
|
+ state_div.value.style.overflow = "hidden";
|
|
|
+ setTimeout(() => {
|
|
|
+ state_div.value.style.height = "auto";
|
|
|
+ }, 500);
|
|
|
+
|
|
|
+ // 设置状态文本
|
|
|
+ state_div.value.innerHTML = "游戏结束,得分:" + Math.floor(score.value);
|
|
|
+}
|
|
|
+
|
|
|
+function game() {
|
|
|
+ init();
|
|
|
+ loop.value = setInterval(gameloop, 20);
|
|
|
+}
|
|
|
+function restart() {
|
|
|
+ // 调用初始化方法
|
|
|
+ backrgound.value.init();
|
|
|
+ squares.value.init();
|
|
|
+ mySquare.value.init();
|
|
|
+
|
|
|
+ // 更新时间戳
|
|
|
+ lastTime.value = Date.now();
|
|
|
+
|
|
|
+ // 隐藏元素
|
|
|
+ state_div.value.style.display = "none";
|
|
|
+ game_title.value.style.display = "none";
|
|
|
+ login_btn.value.style.display = "none";
|
|
|
+
|
|
|
+ // 显示分数
|
|
|
+ score_div.value.style.display = "block";
|
|
|
+
|
|
|
+ // 重置分数和速度
|
|
|
+ score.value = 0;
|
|
|
+ totalSpeed.value = 3;
|
|
|
+}
|
|
|
+function gameloop() {
|
|
|
+ backrgound.value.draw();
|
|
|
+ ctx2.value.clearRect(0, 0, canWidth.value, canHeight.value);
|
|
|
+ ctx2.value.save();
|
|
|
+
|
|
|
+ if (beginAnim.value.isLive && Date.now() - lastTime.value > 1000) {
|
|
|
+ beginAnim.value.draw();
|
|
|
}
|
|
|
-
|
|
|
- interface BeginAnimObj {
|
|
|
- x: number;
|
|
|
- y: number;
|
|
|
- isLive: boolean;
|
|
|
- l: number;
|
|
|
- color: string;
|
|
|
- toDownSpeed: number;
|
|
|
- toVSpeed: number;
|
|
|
- init: () => void;
|
|
|
- jump: () => void;
|
|
|
- toDown: () => void;
|
|
|
- draw: () => void;
|
|
|
+
|
|
|
+ if (beginGame.value && !gameOver.value) {
|
|
|
+ scoreText.value = `得分:${Math.floor(score.value)}`;
|
|
|
+ addSpeed();
|
|
|
+ squares.value.draw();
|
|
|
+ mySquare.value.draw();
|
|
|
+ squaresToMy();
|
|
|
+
|
|
|
+ // 添加点击事件监听器
|
|
|
+ main_box.value.addEventListener("click", function () {
|
|
|
+ mySquare.value.jump();
|
|
|
+ });
|
|
|
+ } else if (gameOver.value && !beginGame.value) {
|
|
|
+ // 这里可以添加游戏结束时的逻辑
|
|
|
}
|
|
|
-
|
|
|
- const can1 = ref<HTMLCanvasElement | null>(null);
|
|
|
- const can2 = ref<HTMLCanvasElement | null>(null);
|
|
|
- const ctx1 = ref<CanvasRenderingContext2D | null>(null);
|
|
|
- const ctx2 = ref<CanvasRenderingContext2D | null>(null);
|
|
|
- const canWidth = ref(820);
|
|
|
- const canHeight = ref(640);
|
|
|
- const maxHeight = ref(window.innerHeight);
|
|
|
- const maxWidth = ref(window.innerWidth);
|
|
|
-
|
|
|
- const beginGame = ref(false);
|
|
|
- const gameOver = ref(false);
|
|
|
- const backrgound = ref<BackgroundObj | null>(null);
|
|
|
- const squares = ref<SquareObj | null>(null);
|
|
|
- const mySquare = ref<MySquareObj | null>(null);
|
|
|
- const beginAnim = ref<BeginAnimObj | null>(null);
|
|
|
- const lastTime = ref(Date.now());
|
|
|
- const changeColorTime = ref(Date.now());
|
|
|
- const changeTimeArrays = ["10", "9", "8", "7", "6", "5", "4", "3", "2", "1", "颜色变化!"];
|
|
|
- const changeColorIndex = ref(0);
|
|
|
- const totalSpeed = ref(3);
|
|
|
- const isStep = ref(false);
|
|
|
- const colorChangeTimeW = ref(0);
|
|
|
- const score = ref(0);
|
|
|
- const showColorChange = ref(false);
|
|
|
-
|
|
|
- const squareColor = ["#FF6688", "#00FF00", "#3399FF", "#FFDAB9", "blueviolet"];
|
|
|
-
|
|
|
- const init = () => {
|
|
|
- score.value = 0;
|
|
|
- beginGame.value = false;
|
|
|
+
|
|
|
+ ctx2.value.restore();
|
|
|
+}
|
|
|
+function loginGame() {
|
|
|
+ changeColorTime.value = Date.now();
|
|
|
+
|
|
|
+ // 显示颜色变化时间div
|
|
|
+ colorChangeTime_div.value.style.display = "block";
|
|
|
+
|
|
|
+ // 随机设置颜色
|
|
|
+ const randomColor =
|
|
|
+ squareColor[Math.floor(Math.random() * squareColor.length)];
|
|
|
+ colorChangeTime_div.value.style.color = randomColor;
|
|
|
+
|
|
|
+ // 设置颜色变化时间div的内容
|
|
|
+ colorChangeTime_div.value.innerHTML = "" + changeTimeArrays[changeColorindex.value];
|
|
|
+
|
|
|
+ if (!gameOver.value && !beginGame.value) {
|
|
|
+ // 显示分数,隐藏游戏标题和方块
|
|
|
+ score_div.value.style.display = "block";
|
|
|
+ game_title.value.style.display = "none";
|
|
|
+ square_main.value.style.display = "none";
|
|
|
+
|
|
|
+ // 设置游戏状态
|
|
|
+ beginGame.value = true;
|
|
|
+
|
|
|
+ // 隐藏登录按钮
|
|
|
+ login_btn.value.style.display = "none";
|
|
|
+ } else if (gameOver.value && !beginGame.value) {
|
|
|
+ // 重新开始游戏
|
|
|
+ restart();
|
|
|
+
|
|
|
+ // 更新游戏状态
|
|
|
gameOver.value = false;
|
|
|
- isStep.value = false;
|
|
|
- lastTime.value = Date.now();
|
|
|
-
|
|
|
- canWidth.value = maxWidth.value !== canWidth.value ? maxWidth.value : canWidth.value;
|
|
|
- canHeight.value = maxHeight.value !== canHeight.value ? maxHeight.value : canHeight.value;
|
|
|
-
|
|
|
- can1.value!.width = canWidth.value;
|
|
|
- can2.value!.width = canWidth.value;
|
|
|
- can1.value!.height = canHeight.value;
|
|
|
- can2.value!.height = canHeight.value;
|
|
|
-
|
|
|
- colorChangeTimeW.value = (canHeight.value > canWidth.value ? canWidth.value : canHeight.value) * 0.5;
|
|
|
-
|
|
|
- backrgound.value = {
|
|
|
- x: [],
|
|
|
- y: [],
|
|
|
- w: [],
|
|
|
- h: [],
|
|
|
- isLive: [],
|
|
|
- num: 3,
|
|
|
- init() {
|
|
|
- for (let i = 0; i < this.num; i++) {
|
|
|
- if (i === 0) {
|
|
|
- this.x[i] = canWidth.value * 0.1 * Math.random();
|
|
|
- } else {
|
|
|
- this.x[i] = this.x[i - 1] + this.w[i - 1] + canWidth.value * 0.2 * i * Math.random();
|
|
|
- }
|
|
|
- this.w[i] = canWidth.value * 0.08 + canHeight.value * Math.random() * 0.3;
|
|
|
- this.h[i] = canHeight.value * 0.08 + canWidth.value * Math.random() * 0.3;
|
|
|
- this.y[i] = canHeight.value * 0.2 * Math.random();
|
|
|
- this.isLive[i] = true;
|
|
|
- }
|
|
|
- },
|
|
|
- draw() {
|
|
|
- ctx1.value!.clearRect(0, 0, canWidth.value, canHeight.value);
|
|
|
- ctx1.value!.save();
|
|
|
- for (let i = 0; i < this.num; i++) {
|
|
|
- if (this.isLive[i]) {
|
|
|
- this.x[i] -= 0.1 * totalSpeed.value;
|
|
|
- ctx1.value!.fillStyle = "#ffffff";
|
|
|
- // Draw cloud logic (simplified)
|
|
|
- // ... (original cloud drawing logic here)
|
|
|
+ beginGame.value = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置动画状态
|
|
|
+ beginAnim.value.isLive = false;
|
|
|
+
|
|
|
+ // 隐藏方块
|
|
|
+ square_main.value.style.display = "none";
|
|
|
+}
|
|
|
+function addSpeed() {
|
|
|
+ totalSpeed.value += 0.04 * 0.05;
|
|
|
+ score.value += 0.04;
|
|
|
+}
|
|
|
+function squaresToMy() {
|
|
|
+ for (var i = 0; i < squares.value.num; i++) {
|
|
|
+ if (squares.value.isLive[i]) {
|
|
|
+ if (squares.value.color[i] != mySquare.value.color) {
|
|
|
+ if (mySquare.value.isLive) {
|
|
|
+ if (
|
|
|
+ ((mySquare.value.x + mySquare.value.l - 1 > squares.value.x[i] &&
|
|
|
+ mySquare.value.x + mySquare.value.l - 1 < squares.value.x[i] + squares.value.w[i] &&
|
|
|
+ mySquare.value.x + mySquare.value.l - 30 > squares.value.x[i] &&
|
|
|
+ mySquare.value.x + mySquare.value.l - 30 <
|
|
|
+ squares.value.x[i] + squares.value.w[i]) ||
|
|
|
+ (mySquare.value.x > squares.value.x[i] &&
|
|
|
+ mySquare.value.x + 10 < squares.value.x[i] + squares.value.w[i] &&
|
|
|
+ mySquare.value.x + 10 > squares.value.x[i] &&
|
|
|
+ mySquare.value.x + 10 < squares.value.x[i] + squares.value.w[i])) &&
|
|
|
+ mySquare.value.y + mySquare.value.l > squares.value.y[i] &&
|
|
|
+ mySquare.value.y + mySquare.value.l < squares.value.y[i] + squares.value.h[i]
|
|
|
+ ) {
|
|
|
+ mySquare.value.y = squares.value.y[i] - mySquare.value.l;
|
|
|
+ mySquare.value.toVSpeed = -totalSpeed.value * 0.2;
|
|
|
+ mySquare.value.toDownSpeed = 0;
|
|
|
+ jump_count.value = 0;
|
|
|
}
|
|
|
- if (this.x[i] + this.w[i] < 0) {
|
|
|
- this.isLive[i] = false;
|
|
|
+ if (
|
|
|
+ mySquare.value.x + mySquare.value.l > squares.value.x[i] &&
|
|
|
+ mySquare.value.x + mySquare.value.l < squares.value.x[i] + squares.value.w[i] &&
|
|
|
+ mySquare.value.y + mySquare.value.l > squares.value.y[i] &&
|
|
|
+ mySquare.value.y + mySquare.value.l < squares.value.y[i] + squares.value.h[i]
|
|
|
+ ) {
|
|
|
+ mySquare.value.x = squares.value.x[i] - mySquare.value.l;
|
|
|
}
|
|
|
}
|
|
|
- ctx1.value!.restore();
|
|
|
- this.cloudBorn();
|
|
|
- },
|
|
|
- cloudBorn() {
|
|
|
- // Cloud reborn logic (simplified)
|
|
|
- // ... (original cloud reborn logic here)
|
|
|
}
|
|
|
- };
|
|
|
-
|
|
|
- squares.value = {
|
|
|
- x: [],
|
|
|
- y: [],
|
|
|
- w: [],
|
|
|
- h: [],
|
|
|
- color: [],
|
|
|
- isLive: [],
|
|
|
- num: 12,
|
|
|
- init() {
|
|
|
- for (let i = 0; i < this.num; i++) {
|
|
|
- this.color[i] = squareColor[Math.floor(Math.random() * squareColor.length)];
|
|
|
- if (i === 0) {
|
|
|
- this.x[i] = 0;
|
|
|
- } else {
|
|
|
- this.x[i] = this.x[i - 1] + this.w[i - 1] + 1;
|
|
|
- }
|
|
|
- this.h[i] = canHeight.value * 0.3 + canHeight.value * 0.25 * Math.random();
|
|
|
- this.w[i] = canWidth.value * 0.15 + canWidth.value * 0.06 * Math.random();
|
|
|
- this.y[i] = canHeight.value - this.h[i];
|
|
|
- this.isLive[i] = true;
|
|
|
- }
|
|
|
- },
|
|
|
- draw() {
|
|
|
- for (let i = 0; i < this.num; i++) {
|
|
|
- if (this.isLive[i]) {
|
|
|
- ctx2.value!.fillStyle = this.color[i];
|
|
|
- ctx2.value!.fillRect(this.x[i], this.y[i], this.w[i], this.h[i]);
|
|
|
- this.x[i] -= totalSpeed.value;
|
|
|
- }
|
|
|
- if (this.x[i] + this.w[i] < 0) {
|
|
|
- this.isLive[i] = false;
|
|
|
- }
|
|
|
- }
|
|
|
- this.squareBorn();
|
|
|
- },
|
|
|
- squareBorn() {
|
|
|
- // Square reborn logic (simplified)
|
|
|
- // ... (original square reborn logic here)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//背景
|
|
|
+class backgroundObj {
|
|
|
+ constructor() {
|
|
|
+ this.x = [];
|
|
|
+ this.y = [];
|
|
|
+ this.w = [];
|
|
|
+ this.h = [];
|
|
|
+ this.isLive = [];
|
|
|
+ this.num = 3;
|
|
|
+ }
|
|
|
+
|
|
|
+ init() {
|
|
|
+ for (let i = 0; i < this.num; i++) {
|
|
|
+ this.x[i] =
|
|
|
+ i === 0
|
|
|
+ ? canWidth.value * 0.1 * Math.random()
|
|
|
+ : this.x[i - 1] +
|
|
|
+ this.w[i - 1] +
|
|
|
+ canWidth.value * 0.2 * i * Math.random();
|
|
|
+
|
|
|
+ this.w[i] = canWidth.value * 0.08 + canHeight.value * Math.random() * 0.3;
|
|
|
+ this.h[i] = canHeight.value * 0.08 + canWidth.value * Math.random() * 0.3;
|
|
|
+ this.y[i] = canHeight.value * 0.2 * Math.random();
|
|
|
+ this.isLive[i] = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ cloudBorn() {
|
|
|
+ for (let i = 0; i < this.num; i++) {
|
|
|
+ if (!this.isLive[i]) {
|
|
|
+ this.w[i] = canWidth.value * 0.08 + canWidth.value * Math.random() * 0.3;
|
|
|
+ this.h[i] = canHeight.value * 0.08 + canHeight.value * Math.random() * 0.3;
|
|
|
+ this.y[i] = canHeight.value * 0.2 * Math.random();
|
|
|
+
|
|
|
+ this.x[i] = i === 0 ? canWidth.value : canWidth.value + i * this.w[i - 1];
|
|
|
+
|
|
|
+ this.isLive[i] = true;
|
|
|
}
|
|
|
- };
|
|
|
-
|
|
|
- mySquare.value = {
|
|
|
- x: 0,
|
|
|
- y: 0,
|
|
|
- isLive: true,
|
|
|
- l: 40,
|
|
|
- color: squareColor[0],
|
|
|
- toDownSpeed: 0,
|
|
|
- toVSpeed: 0,
|
|
|
- init() {
|
|
|
- this.x = 0;
|
|
|
- this.y = 0;
|
|
|
- this.isLive = true;
|
|
|
- this.l = 40;
|
|
|
- this.toDownSpeed = 0;
|
|
|
- this.toVSpeed = 0;
|
|
|
- this.color = squareColor[0];
|
|
|
- },
|
|
|
- jump() {
|
|
|
- if (this.isLive) {
|
|
|
- this.toDownSpeed = -15;
|
|
|
- this.toVSpeed = 2;
|
|
|
- }
|
|
|
- },
|
|
|
- toDown() {
|
|
|
- if (this.isLive) {
|
|
|
- this.toDownSpeed += 9.8 * 1 * 0.06;
|
|
|
- this.y += this.toDownSpeed;
|
|
|
- this.x += this.toVSpeed;
|
|
|
- if (this.y + this.l > canHeight.value) {
|
|
|
- this.isLive = false;
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- draw() {
|
|
|
- if (this.isLive) {
|
|
|
- const now = Date.now();
|
|
|
- if (now - changeColorTime.value > 1000) {
|
|
|
- changeColorIndex.value = ++changeColorIndex.value % changeTimeArrays.length;
|
|
|
- const strColor = squareColor[Math.floor(Math.random() * squareColor.length)];
|
|
|
- document.getElementById("colorChangeTime_div")!.style.color = strColor;
|
|
|
- document.getElementById("colorChangeTime_div")!.innerHTML = changeTimeArrays[changeColorIndex.value];
|
|
|
- if (changeColorIndex.value === 10) {
|
|
|
- document.getElementById("colorChangeTime_div")!.style.fontSize = colorChangeTimeW.value * 0.15 + "px";
|
|
|
- this.color = strColor;
|
|
|
- } else {
|
|
|
- document.getElementById("colorChangeTime_div")!.style.fontSize = colorChangeTimeW.value * 0.3 + "px";
|
|
|
- }
|
|
|
- changeColorTime.value = now;
|
|
|
- }
|
|
|
- ctx2.value!.fillStyle = this.color;
|
|
|
- ctx2.value!.fillRect(this.x, this.y, this.l, this.l);
|
|
|
- ctx2.value!.strokeStyle = "#ffffff";
|
|
|
- ctx2.value!.strokeRect(this.x, this.y, this.l, this.l);
|
|
|
- if (this.x < -100) {
|
|
|
- this.isLive = false;
|
|
|
- }
|
|
|
- } else {
|
|
|
- restartInit();
|
|
|
- }
|
|
|
- this.toDown();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ draw() {
|
|
|
+ ctx1.value.clearRect(0, 0, canWidth.value, canHeight.value);
|
|
|
+ ctx1.value.save();
|
|
|
+
|
|
|
+ for (let i = 0; i < this.num; i++) {
|
|
|
+ if (!this.isLive[i]) continue;
|
|
|
+
|
|
|
+ this.x[i] -= 0.1 * totalSpeed.value;
|
|
|
+ const maxSize = Math.max(this.h[i], this.w[i]) * 0.15;
|
|
|
+ const smallSize = Math.max(this.h[i], this.w[i]) * 0.1;
|
|
|
+
|
|
|
+ // 绘制云朵的各个部分
|
|
|
+ const cloudParts = [
|
|
|
+ { x: 0.4, y: 0.1, size: maxSize },
|
|
|
+ { x: 0.1, y: 0.2, size: maxSize },
|
|
|
+ { x: 0.6, y: 0.25, size: maxSize },
|
|
|
+ { x: 0.5, y: 0.3, size: maxSize },
|
|
|
+ { x: 0.65, y: 0.22, size: maxSize },
|
|
|
+ { x: 0.2, y: 0.35, size: maxSize },
|
|
|
+ { x: 0.35, y: 0.35, size: smallSize },
|
|
|
+ { x: 0.3, y: 0.1, size: maxSize },
|
|
|
+ ];
|
|
|
+
|
|
|
+ ctx1.value.fillStyle = "#ffffff";
|
|
|
+ cloudParts.forEach((part) => {
|
|
|
+ ctx1.value.beginPath();
|
|
|
+ ctx1.value.arc(
|
|
|
+ this.x[i] + this.w[i] * part.x,
|
|
|
+ this.y[i] + this.h[i] * part.y,
|
|
|
+ part.size,
|
|
|
+ 0,
|
|
|
+ Math.PI * 2
|
|
|
+ );
|
|
|
+ ctx1.value.fill();
|
|
|
+ ctx1.value.closePath();
|
|
|
+ });
|
|
|
+
|
|
|
+ if (this.x[i] + this.w[i] < 0) {
|
|
|
+ this.isLive[i] = false;
|
|
|
}
|
|
|
- };
|
|
|
-
|
|
|
- beginAnim.value = {
|
|
|
- x: 0,
|
|
|
- y: 0,
|
|
|
- isLive: true,
|
|
|
- l: 40,
|
|
|
- color: squareColor[0],
|
|
|
- toDownSpeed: 0,
|
|
|
- toVSpeed: canWidth.value * 0.021,
|
|
|
- init() {
|
|
|
- this.isLive = true;
|
|
|
- this.x = 0;
|
|
|
- this.y = 0;
|
|
|
- this.l = 40;
|
|
|
- this.toDownSpeed = 0;
|
|
|
- this.toVSpeed = canWidth.value * 0.021;
|
|
|
- this.color = squareColor[0];
|
|
|
- },
|
|
|
- jump() {
|
|
|
- if (this.isLive) {
|
|
|
- this.toDownSpeed = -this.toDownSpeed;
|
|
|
- this.toVSpeed = canWidth.value * 0.021 * 0.5;
|
|
|
- this.x += this.toVSpeed;
|
|
|
- if (this.toVSpeed + 2 < 3) {
|
|
|
- this.toVSpeed += 1;
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- toDown() {
|
|
|
- if (this.isLive) {
|
|
|
- this.toDownSpeed += 9.8 * 1 * 0.06;
|
|
|
- this.y += this.toDownSpeed;
|
|
|
- this.x += this.toVSpeed;
|
|
|
- if (this.y > canHeight.value) {
|
|
|
- this.isLive = false;
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- draw() {
|
|
|
- if (this.isLive) {
|
|
|
- const squareMain = document.getElementById("square_main")!;
|
|
|
- squareMain.style.left = this.x + "px";
|
|
|
- squareMain.style.top = this.y + "px";
|
|
|
- if (
|
|
|
- this.y + this.l > canHeight.value * 0.35 &&
|
|
|
- this.x + this.l * 0.5 < canWidth.value * 0.5 + 120 &&
|
|
|
- this.x + this.l * 0.5 > canWidth.value * 0.5 - 120
|
|
|
- ) {
|
|
|
- this.jump();
|
|
|
- document.getElementById("game_title")!.innerHTML = "方 块 <i style='font-size: 46px;color:#FF6688;'>跳 </i>跃";
|
|
|
- }
|
|
|
- this.toDown();
|
|
|
- } else {
|
|
|
- const squareMain = document.getElementById("square_main")!;
|
|
|
- squareMain.style.display = "none";
|
|
|
+ }
|
|
|
+
|
|
|
+ ctx1.value.restore();
|
|
|
+ this.cloudBorn();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//底下方块
|
|
|
+class squareObj {
|
|
|
+ constructor() {
|
|
|
+ this.num = 12;
|
|
|
+ this.x = [];
|
|
|
+ this.y = [];
|
|
|
+ this.w = [];
|
|
|
+ this.h = [];
|
|
|
+ this.color = [];
|
|
|
+ this.isLive = [];
|
|
|
+ }
|
|
|
+
|
|
|
+ init() {
|
|
|
+ let repeatColorCount = 0;
|
|
|
+
|
|
|
+ for (let i = 0; i < this.num; i++) {
|
|
|
+ // Random color selection with constraints
|
|
|
+ this.color[i] = this.getRandomColor(i, repeatColorCount);
|
|
|
+
|
|
|
+ // Position and size initialization
|
|
|
+ if (i === 0) {
|
|
|
+ this.x[i] = 0;
|
|
|
+ } else {
|
|
|
+ this.x[i] = this.x[i - 1] + this.w[i - 1] + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.h[i] = canHeight.value * 0.3 + canHeight.value * 0.25 * Math.random();
|
|
|
+ this.w[i] = canWidth.value * 0.15 + canWidth.value * 0.06 * Math.random();
|
|
|
+ this.y[i] = canHeight.value - this.h[i];
|
|
|
+ this.isLive[i] = true;
|
|
|
+
|
|
|
+ // Update repeat color count
|
|
|
+ repeatColorCount =
|
|
|
+ this.color[i] === this.color[i - 1] ? repeatColorCount + 1 : 0;
|
|
|
+
|
|
|
+ // Handle consecutive colors
|
|
|
+ if (repeatColorCount > 1) {
|
|
|
+ this.adjustColor(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ getRandomColor(i: any, repeatColorCount: any) {
|
|
|
+ const randomIndex = Math.floor(Math.random() * squareColor.length);
|
|
|
+ let color = squareColor[randomIndex];
|
|
|
+
|
|
|
+ // For the first element, check against last element
|
|
|
+ if (i === 0 && color === this.color[this.num - 1]) {
|
|
|
+ const lastColorIndex = squareColor.indexOf(
|
|
|
+ this.color[this.num - 1]
|
|
|
+ );
|
|
|
+ color =
|
|
|
+ squareColor[
|
|
|
+ (lastColorIndex - 1 + squareColor.length) % squareColor.length
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ // For other elements, check against previous element
|
|
|
+ else if (
|
|
|
+ i > 0 &&
|
|
|
+ color === this.color[i - 1] &&
|
|
|
+ repeatColorCount > 1
|
|
|
+ ) {
|
|
|
+ const currentColorIndex = squareColor.indexOf(color);
|
|
|
+ color = squareColor[(currentColorIndex + 1) % squareColor.length];
|
|
|
+ }
|
|
|
+
|
|
|
+ return color;
|
|
|
+ }
|
|
|
+
|
|
|
+ adjustColor(i: any) {
|
|
|
+ if (i === 0) {
|
|
|
+ const lastColorIndex = squareColor.indexOf(
|
|
|
+ this.color[this.num - 1]
|
|
|
+ );
|
|
|
+ this.color[i] =
|
|
|
+ squareColor[
|
|
|
+ (lastColorIndex - 1 + squareColor.length) % squareColor.length
|
|
|
+ ];
|
|
|
+ } else {
|
|
|
+ const currentColorIndex = squareColor.indexOf(this.color[i]);
|
|
|
+ this.color[i] =
|
|
|
+ squareColor[(currentColorIndex + 1) % squareColor.length];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ squareBorn() {
|
|
|
+ const maxX = Math.max(
|
|
|
+ ...this.x.map((val, idx) => val + (this.w[idx] || 0))
|
|
|
+ );
|
|
|
+ const maxI = this.x.indexOf(
|
|
|
+ maxX - (this.w[this.x.indexOf(maxX)] || 0)
|
|
|
+ );
|
|
|
+
|
|
|
+ for (let i = 0; i < this.num; i++) {
|
|
|
+ if (!this.isLive[i]) {
|
|
|
+ this.x[i] = maxX + 1;
|
|
|
+ this.h[i] = canHeight.value * 0.25 + canHeight.value * 0.35 * Math.random();
|
|
|
+ this.w[i] = canWidth.value * 0.14 + canWidth.value * 0.1 * Math.random();
|
|
|
+ this.y[i] = canHeight - this.h[i];
|
|
|
+
|
|
|
+ let repeatColorCount = 0;
|
|
|
+ if (i === 0 && this.isLive[this.num - 1]) {
|
|
|
+ this.color[i] = this.getRandomColorForBorn(
|
|
|
+ this.num - 1,
|
|
|
+ repeatColorCount
|
|
|
+ );
|
|
|
+ } else if (i > 0 && this.isLive[i - 1]) {
|
|
|
+ this.color[i] = this.getRandomColorForBorn(
|
|
|
+ i - 1,
|
|
|
+ repeatColorCount
|
|
|
+ );
|
|
|
}
|
|
|
+
|
|
|
+ this.isLive[i] = true;
|
|
|
+ return;
|
|
|
}
|
|
|
- };
|
|
|
-
|
|
|
- backrgound.value.init();
|
|
|
- squares.value.init();
|
|
|
- mySquare.value.init();
|
|
|
- beginAnim.value.init();
|
|
|
- };
|
|
|
-
|
|
|
- const restart = () => {
|
|
|
- backrgound.value!.init();
|
|
|
- squares.value!.init();
|
|
|
- mySquare.value!.init();
|
|
|
- lastTime.value = Date.now();
|
|
|
- document.getElementById("state")!.style.display = "none";
|
|
|
- document.getElementById("game_title")!.style.display = "none";
|
|
|
- document.getElementById("login_btn")!.style.display = "none";
|
|
|
- document.getElementById("score")!.style.display = "block";
|
|
|
- score.value = 0;
|
|
|
- totalSpeed.value = 3;
|
|
|
- };
|
|
|
-
|
|
|
- const gameloop = () => {
|
|
|
- backrgound.value!.draw();
|
|
|
- ctx2.value!.clearRect(0, 0, canWidth.value, canHeight.value);
|
|
|
- ctx2.value!.save();
|
|
|
- if (beginAnim.value!.isLive && Date.now() - lastTime.value > 1000) {
|
|
|
- beginAnim.value!.draw();
|
|
|
}
|
|
|
-
|
|
|
- if (beginGame.value && !gameOver.value) {
|
|
|
- document.getElementById("score")!.innerHTML = "得分:" + Math.floor(score.value);
|
|
|
- addSpeed();
|
|
|
- squares.value!.draw();
|
|
|
- mySquare.value!.draw();
|
|
|
- // squaresToMy(); // Collision detection logic needs to be adapted for Vue
|
|
|
+ }
|
|
|
+
|
|
|
+ getRandomColorForBorn(prevIndex: any, repeatColorCount: any) {
|
|
|
+ const randomIndex = Math.floor(Math.random() * 3);
|
|
|
+ let color = squareColor[randomIndex];
|
|
|
+
|
|
|
+ if (color === this.color[prevIndex] && repeatColorCount > 1) {
|
|
|
+ const currentColorIndex = squareColor.indexOf(color);
|
|
|
+ color = squareColor[(currentColorIndex + 1) % squareColor.length];
|
|
|
}
|
|
|
- ctx2.value!.restore();
|
|
|
- };
|
|
|
-
|
|
|
- const loginGame = () => {
|
|
|
- changeColorTime.value = Date.now();
|
|
|
- document.getElementById("colorChangeTime_div")!.style.display = "block";
|
|
|
- document.getElementById("colorChangeTime_div")!.style.color = squareColor[Math.floor(Math.random() * squareColor.length)];
|
|
|
- document.getElementById("colorChangeTime_div")!.innerHTML = changeTimeArrays[changeColorIndex.value];
|
|
|
- if (!gameOver.value && !beginGame.value) {
|
|
|
- document.getElementById("score")!.style.display = "block";
|
|
|
- document.getElementById("game_title")!.style.display = "none";
|
|
|
- document.getElementById("square_main")!.style.display = "none";
|
|
|
- beginGame.value = true;
|
|
|
- document.getElementById("login_btn")!.style.display = "none";
|
|
|
- } else if (gameOver.value && !beginGame.value) {
|
|
|
- restart();
|
|
|
- gameOver.value = false;
|
|
|
- beginGame.value = true;
|
|
|
+
|
|
|
+ return color;
|
|
|
+ }
|
|
|
+
|
|
|
+ draw() {
|
|
|
+ for (let i = 0; i < this.num; i++) {
|
|
|
+ if (this.isLive[i]) {
|
|
|
+ ctx2.value.fillStyle = this.color[i];
|
|
|
+ ctx2.value.beginPath();
|
|
|
+ ctx2.value.fillRect(this.x[i], this.y[i], this.w[i], this.h[i]);
|
|
|
+ ctx2.value.fill();
|
|
|
+ ctx2.value.closePath();
|
|
|
+ this.x[i] -= totalSpeed.value;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.x[i] + this.w[i] < 0) {
|
|
|
+ this.isLive[i] = false;
|
|
|
+ }
|
|
|
}
|
|
|
- beginAnim.value!.isLive = false;
|
|
|
- document.getElementById("square_main")!.style.display = "none";
|
|
|
- };
|
|
|
-
|
|
|
- const addSpeed = () => {
|
|
|
- totalSpeed.value += 0.04 * 0.05;
|
|
|
- score.value += 0.04;
|
|
|
- };
|
|
|
-
|
|
|
- const restartInit = () => {
|
|
|
- changeColorIndex.value = 0;
|
|
|
- document.getElementById("colorChangeTime_div")!.style.display = "none";
|
|
|
- beginAnim.value!.init();
|
|
|
- beginGame.value = false;
|
|
|
- gameOver.value = true;
|
|
|
- lastTime.value = Date.now();
|
|
|
- document.getElementById("game_title")!.innerHTML = "方 块 跳 跃";
|
|
|
- document.getElementById("score")!.style.display = "none";
|
|
|
- document.getElementById("game_title")!.style.display = "block";
|
|
|
- document.getElementById("login_btn")!.style.display = "block";
|
|
|
- document.getElementById("login_btn")!.innerHTML = "再来一次";
|
|
|
- document.getElementById("state")!.style.display = "block";
|
|
|
- document.getElementById("state")!.innerHTML = "游戏结束,得分:" + Math.floor(score.value);
|
|
|
- };
|
|
|
-
|
|
|
- onMounted(() => {
|
|
|
- ctx1.value = can1.value!.getContext("2d");
|
|
|
- ctx2.value = can2.value!.getContext("2d");
|
|
|
- init();
|
|
|
- const loop = setInterval(gameloop, 20);
|
|
|
- onBeforeUnmount(() => clearInterval(loop));
|
|
|
- });
|
|
|
- </script>
|
|
|
-
|
|
|
- <style scoped>
|
|
|
- /* CSS styles from the original HTML */
|
|
|
- #main_box {
|
|
|
- margin: 0px auto;
|
|
|
- width: 420px;
|
|
|
- height: 580px;
|
|
|
- background: skyblue;
|
|
|
- position: relative;
|
|
|
- overflow: hidden;
|
|
|
- z-index: 9999;
|
|
|
+
|
|
|
+ this.squareBorn();
|
|
|
}
|
|
|
- .can {
|
|
|
- position: absolute;
|
|
|
- top: 0px;
|
|
|
- left: 0px;
|
|
|
+}
|
|
|
+
|
|
|
+//我的方块
|
|
|
+class mySquareObj {
|
|
|
+ constructor() {
|
|
|
+ this.x;
|
|
|
+ this.y;
|
|
|
+ this.isLive; // 生命状态
|
|
|
+ this.l = 40; // 正方形边长
|
|
|
+ this.color;
|
|
|
+ this.toDownSpeed = 0; // 垂直方向速度
|
|
|
+ this.toVSpeed = 0; // 水平方向速度
|
|
|
}
|
|
|
- #score {
|
|
|
- width: auto;
|
|
|
- height: 40px;
|
|
|
- font-size: 22px;
|
|
|
- color: #7fffd4;
|
|
|
- position: absolute;
|
|
|
- top: 10px;
|
|
|
- left: 10px;
|
|
|
+
|
|
|
+ init() {
|
|
|
+ this.isLive = true;
|
|
|
+ this.x = 0;
|
|
|
+ this.y = 0;
|
|
|
+ this.l = 40;
|
|
|
+ this.toDownSpeed = 0;
|
|
|
+ this.toVSpeed = 0;
|
|
|
+ this.color = squareColor[0];
|
|
|
}
|
|
|
- #game_title {
|
|
|
- display: none;
|
|
|
- position: absolute;
|
|
|
- width: 240px;
|
|
|
- height: 80px;
|
|
|
- line-height: 80px;
|
|
|
- text-align: center;
|
|
|
- top: 35%;
|
|
|
- left: 50%;
|
|
|
- margin-left: -120px;
|
|
|
- font-size: 42px;
|
|
|
- font-family: "century gothic";
|
|
|
- font-weight: bolder;
|
|
|
- text-shadow: 4px 3px 2px black;
|
|
|
- color: #fff;
|
|
|
+
|
|
|
+ jump() {
|
|
|
+ if (this.isLive) {
|
|
|
+ this.toDownSpeed = -15;
|
|
|
+ this.toVSpeed = 2;
|
|
|
+ jump_count.value++;
|
|
|
+ if (this.x + this.l > canWidth.value) {
|
|
|
+ this.x = canWidth.value - this.l;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ toDown() {
|
|
|
+ if (this.isLive) {
|
|
|
+ this.toDownSpeed += 9.8 * 1 * 0.06;
|
|
|
+ this.y += this.toDownSpeed;
|
|
|
+ this.x += this.toVSpeed;
|
|
|
+ if (this.y + this.l > canHeight.value) {
|
|
|
+ this.isLive = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- #login_btn {
|
|
|
- display: none;
|
|
|
- position: absolute;
|
|
|
- bottom: 100px;
|
|
|
- left: 50%;
|
|
|
- width: 100px;
|
|
|
- height: 40px;
|
|
|
- margin-left: -50px;
|
|
|
- line-height: 40px;
|
|
|
- text-align: center;
|
|
|
- border-radius: 12px;
|
|
|
- border: 2px solid #ffffff;
|
|
|
- font-size: 18px;
|
|
|
- color: #000000;
|
|
|
- font-weight: normal;
|
|
|
- background: peachpuff;
|
|
|
+
|
|
|
+ draw() {
|
|
|
+ if (this.isLive) {
|
|
|
+ const now = Date.now();
|
|
|
+ if (now - changeColorTime.value > 1000) {
|
|
|
+ changeColorindex.value = ++changeColorindex.value % changeTimeArrays.length;
|
|
|
+ const strColor =
|
|
|
+ "" +
|
|
|
+ squareColor[Math.floor(Math.random() * squareColor.length)];
|
|
|
+
|
|
|
+
|
|
|
+ // 设置颜色和内容
|
|
|
+ colorChangeTime_div.value.style.color = strColor;
|
|
|
+ colorChangeTime_div.value.textContent =
|
|
|
+ "" + changeTimeArrays[changeColorindex.value];
|
|
|
+
|
|
|
+ if (changeColorindex.value === 10) {
|
|
|
+ colorChangeTime_div.value.style.fontSize =
|
|
|
+ colorChangeTimeW * 0.15 + "px";
|
|
|
+ this.color = strColor;
|
|
|
+ } else {
|
|
|
+ colorChangeTime_div.value.style.fontSize =
|
|
|
+ colorChangeTimeW * 0.3 + "px";
|
|
|
+ }
|
|
|
+
|
|
|
+ changeColorTime.value = now;
|
|
|
+ }
|
|
|
+ ctx2.value.fillStyle = this.color + "";
|
|
|
+ ctx2.value.rect(this.x, this.y, this.l, this.l);
|
|
|
+ ctx2.value.fill();
|
|
|
+ ctx2.value.lineWidth = 3;
|
|
|
+ ctx2.value.radiusX = 3;
|
|
|
+
|
|
|
+ ctx2.value.strokeStyle = "#ffffff";
|
|
|
+ ctx2.value.stroke();
|
|
|
+ if (this.x < -100) {
|
|
|
+ this.isLive = false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ restartInit();
|
|
|
+ }
|
|
|
+ this.toDown();
|
|
|
}
|
|
|
- #login_btn:hover {
|
|
|
- color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+//动画
|
|
|
+class beginAnimObj {
|
|
|
+ constructor() {
|
|
|
+ this.x;
|
|
|
+ this.y;
|
|
|
+ this.isLive;
|
|
|
+ this.l = 40; // 正方形边长
|
|
|
+ this.color;
|
|
|
+ this.toDownSpeed = 0; // 垂直方向速度
|
|
|
+ this.toVSpeed = canWidth.value * 0.021; // 水平方向速度
|
|
|
}
|
|
|
- #login_btn:active {
|
|
|
- background: #ffffff;
|
|
|
- color: #000000;
|
|
|
+
|
|
|
+ init() {
|
|
|
+ this.isLive = true;
|
|
|
+ this.x = 0;
|
|
|
+ this.y = 0;
|
|
|
+ this.toDownSpeed = 0;
|
|
|
+ this.toVSpeed = canWidth.value * 0.021;
|
|
|
+ this.color = squareColor[0];
|
|
|
}
|
|
|
- #square_main {
|
|
|
- width: 40px;
|
|
|
- height: 40px;
|
|
|
- position: absolute;
|
|
|
- border: 2px solid #ffffff;
|
|
|
- display: none;
|
|
|
- background: #ff6688;
|
|
|
+
|
|
|
+ jump() {
|
|
|
+ if (this.isLive) {
|
|
|
+ this.toDownSpeed = -this.toDownSpeed;
|
|
|
+ this.toVSpeed = canWidth.value * 0.021 * 0.5;
|
|
|
+ jump_count.value++;
|
|
|
+ if (this.x + this.l > canWidth.value) {
|
|
|
+ this.x = canWidth.value - this.l;
|
|
|
+ }
|
|
|
+ this.x += this.toVSpeed;
|
|
|
+ if (this.toVSpeed + 2 < 3) {
|
|
|
+ this.toVSpeed += 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- #state {
|
|
|
- width: 280px;
|
|
|
- height: 60px;
|
|
|
- font-size: 18px;
|
|
|
- font-weight: bolder;
|
|
|
- text-shadow: #fdf5e6;
|
|
|
- color: blueviolet;
|
|
|
- font-family: "arial narrow";
|
|
|
- position: absolute;
|
|
|
- top: 45%;
|
|
|
- left: 50%;
|
|
|
- line-height: 60px;
|
|
|
- text-align: center;
|
|
|
- margin-left: -140px;
|
|
|
- display: none;
|
|
|
+
|
|
|
+ toDown() {
|
|
|
+ if (this.isLive) {
|
|
|
+ this.toDownSpeed += 9.8 * 1 * 0.06;
|
|
|
+ this.y += this.toDownSpeed;
|
|
|
+ this.x += this.toVSpeed;
|
|
|
+ if (this.y > canHeight.value) {
|
|
|
+ this.isLive = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- #colorChangeTime_div {
|
|
|
- width: 200px;
|
|
|
- height: 50px;
|
|
|
- line-height: 50px;
|
|
|
- position: absolute;
|
|
|
- text-align: center;
|
|
|
- top: 3%;
|
|
|
- left: 50%;
|
|
|
- display: none;
|
|
|
- color: #ffffff;
|
|
|
- font-size: 40px;
|
|
|
+
|
|
|
+ draw() {
|
|
|
+ if (this.isLive) {
|
|
|
+
|
|
|
+ square_main.value.style.display = "block";
|
|
|
+ square_main.value.style.left = this.x + "px";
|
|
|
+ square_main.value.style.top = this.y + "px";
|
|
|
+
|
|
|
+ if (
|
|
|
+ this.y + this.l > canHeight.value * 0.35 &&
|
|
|
+ this.x + this.l * 0.5 < canWidth.value * 0.5 + 120 &&
|
|
|
+ this.x + this.l * 0.5 > canWidth.value * 0.5 - 120
|
|
|
+ ) {
|
|
|
+ this.jump();
|
|
|
+ game_title.value.innerHTML =
|
|
|
+ "方 块 <i style='font-size: 46px;color:#FF6688;'>跳 </i>跃";
|
|
|
+ }
|
|
|
+
|
|
|
+ ctx2.value.restore();
|
|
|
+ this.toDown();
|
|
|
+ } else {
|
|
|
+ square_main.value.style.display = "none";
|
|
|
+ }
|
|
|
}
|
|
|
- </style>
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ game();
|
|
|
+});
|
|
|
+
|
|
|
+onBeforeUnmount(() => {
|
|
|
+ clearInterval(loop.value);
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+* {
|
|
|
+ padding: 0px;
|
|
|
+ margin: 0px;
|
|
|
+}
|
|
|
+
|
|
|
+a {
|
|
|
+ text-decoration: none;
|
|
|
+ list-style: none;
|
|
|
+ color: rgb(0, 0, 0);
|
|
|
+}
|
|
|
+
|
|
|
+#main_box {
|
|
|
+ margin: 0px auto;
|
|
|
+ width: 420px;
|
|
|
+ height: 580px;
|
|
|
+ background: skyblue;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.can {
|
|
|
+ position: absolute;
|
|
|
+ top: 0px;
|
|
|
+ left: 0px;
|
|
|
+}
|
|
|
+
|
|
|
+#score {
|
|
|
+ width: auto;
|
|
|
+ height: 40px;
|
|
|
+ font-size: 22px;
|
|
|
+ color: #7fffd4;
|
|
|
+ position: absolute;
|
|
|
+ top: 10px;
|
|
|
+ left: 10px;
|
|
|
+ display: none;
|
|
|
+}
|
|
|
+
|
|
|
+#game_title {
|
|
|
+ display: none;
|
|
|
+ position: absolute;
|
|
|
+ width: 240px;
|
|
|
+ height: 80px;
|
|
|
+ line-height: 80px;
|
|
|
+ text-align: center;
|
|
|
+ top: 35%;
|
|
|
+ left: 50%;
|
|
|
+ margin-left: -120px;
|
|
|
+ font-size: 42px;
|
|
|
+ font-family: "century gothic";
|
|
|
+ font-weight: bolder;
|
|
|
+ text-shadow: 4px 3px 2px black;
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+#login_btn {
|
|
|
+ display: none;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 100px;
|
|
|
+ left: 50%;
|
|
|
+ width: 100px;
|
|
|
+ height: 40px;
|
|
|
+ margin-left: -50px;
|
|
|
+ line-height: 40px;
|
|
|
+ text-align: center;
|
|
|
+ border-radius: 12px;
|
|
|
+ border: 2px solid #ffffff;
|
|
|
+ font-size: 18px;
|
|
|
+ color: #000000;
|
|
|
+ font-weight: normal;
|
|
|
+ background: peachpuff;
|
|
|
+}
|
|
|
+
|
|
|
+#login_btn:hover {
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+#login_btn:active {
|
|
|
+ background: #ffffff;
|
|
|
+ color: #000000;
|
|
|
+}
|
|
|
+
|
|
|
+#square_main {
|
|
|
+ width: 40px;
|
|
|
+ height: 40px;
|
|
|
+ position: absolute;
|
|
|
+ top: 0px;
|
|
|
+ left: 0px;
|
|
|
+ border: 2px solid #ffffff;
|
|
|
+ display: none;
|
|
|
+ background: #ff6688;
|
|
|
+}
|
|
|
+
|
|
|
+#state {
|
|
|
+ width: 280px;
|
|
|
+ height: 60px;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: bolder;
|
|
|
+ text-shadow: #fdf5e6;
|
|
|
+ color: blueviolet;
|
|
|
+ font-family: "arial narrow";
|
|
|
+ position: absolute;
|
|
|
+ top: 45%;
|
|
|
+ left: 50%;
|
|
|
+ line-height: 60px;
|
|
|
+ text-align: center;
|
|
|
+ margin-left: -140px;
|
|
|
+ display: none;
|
|
|
+}
|
|
|
+
|
|
|
+#colorChangeTime_div {
|
|
|
+ width: 200px;
|
|
|
+ height: 50px;
|
|
|
+ line-height: 50px;
|
|
|
+ position: absolute;
|
|
|
+ text-align: center;
|
|
|
+ top: 3%;
|
|
|
+ left: 50%;
|
|
|
+ display: none;
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 40px;
|
|
|
+}
|
|
|
+</style>
|