Olen kysellyt vinkkejä toisella foorumilla, saamatta vastausta.
Kehittämässäni pelissä ns. vihollis hahmot ovat nyt tallennettu hahmoista huolehtivaan listaan objekteihin, jotka sisältävät sijaintitiedot, sekä hahmo laji kohtaiset ominaisuudet. Uudelle hahmolle arvotaan ensin laji (väri), jonka perusteella uudelle objektille haetaan ennalta määritellyt lajikohtaiset ominaisuudet toisesta objektista (listalta johon on tallennettu ennalta määritellyt ominaisuudet). Tämän lisäksi uudelle hahmolle arvotaan nopeus ja sijainti.
Nykyinen ratkaisu riittänee hyvin projektiini. Ratkaisu ei liene kovinkaan hyvä ja haluaisin luoda paremman tavan hahmojen hallintaan ja ylläpitoon. Hahmot sisältävät paljon samaa tietoa, mutta niitä tulee käsitellä hieman eritavoin. Hahmoista (keltainen, sininen) saa erimäärän pisteitä ja joitakin (punaisia) hahmoja tulee varoa.
verkkopeli
Pelin koodit:
Pelissä on toki muitakin kehityskohtia, myös niitä saa ja kannattaa tuoda esille.
edit. pelin koodit liitetty viestiin.
Kehittämässäni pelissä ns. vihollis hahmot ovat nyt tallennettu hahmoista huolehtivaan listaan objekteihin, jotka sisältävät sijaintitiedot, sekä hahmo laji kohtaiset ominaisuudet. Uudelle hahmolle arvotaan ensin laji (väri), jonka perusteella uudelle objektille haetaan ennalta määritellyt lajikohtaiset ominaisuudet toisesta objektista (listalta johon on tallennettu ennalta määritellyt ominaisuudet). Tämän lisäksi uudelle hahmolle arvotaan nopeus ja sijainti.
Nykyinen ratkaisu riittänee hyvin projektiini. Ratkaisu ei liene kovinkaan hyvä ja haluaisin luoda paremman tavan hahmojen hallintaan ja ylläpitoon. Hahmot sisältävät paljon samaa tietoa, mutta niitä tulee käsitellä hieman eritavoin. Hahmoista (keltainen, sininen) saa erimäärän pisteitä ja joitakin (punaisia) hahmoja tulee varoa.
verkkopeli
Pelin koodit:
JavaScript:
const gameVersion = "v0.6.0"
var movementInterval; // Muuttuja liikkeen päivitystä varten
let gameDifficulty = 0;
// Määritä enimmäiskalatilanne peliruudulla
// NOTICE const alkuliite muutettu, jotta pelin vaikeutumisen yhteydessä ruudussa olevien kalojen määrää voidaan lisätä
let maxFishCount = 5; // Esimerkki: Enimmillään ruudulla voi olla 5 kalaa samanaikaisesti
var gameOver = false; // Alustetaan peli lopetetuksi
var score = 0; // Alustetaan pistemäärä nollaksi
// NOTICE lisätty muuttuja, johon ChatGPT on viitannut luomassaan koodissa
let normalSpeed = 1
// NOTICE lisätty muuttuja, johon ChatGPT on viitannut luomassaan koodissa
let time = 0
// Alkuperäinen pelaajan kalan position arvo
var initialPlayerPosition = 150;
var fishCount = 0; // Alustetaan generoitujen kalojen määrä nollaksi
// Pelaajan kalan tiedot
var playerFish = {
id: 1,
// NOTICE lisätty muuttuja ChatGPT'n muuttuja viittauksen pohjalta
positionX: 40, // NOTICE arvoa muutettu, ettei kala ole pelialueen reunassa kiinni
positionY: initialPlayerPosition,
position: 30,
level: 1,
color: "orange",
// NOTICE nopeus arvo muutettu takaisin alkuperäiseen kuosiinsa (Viimeisin keskustelu, versio v0.2.1)
speed: normalSpeed,
width: 50, // Kalan leveys
height: 30, // Kalan korkeus
eye: {
x: 38,
y: -5,
radius: 5
},
pupil: {
x: 1,
y: 0,
radius: 2.5
}
};
const fishColorsData = [
{
color: "red",
width: 56,
height: 36,
eye: { x: 12, y: -5, radius: 6},
pupil: { x: -1, y: 0, radius: 3},
onCollision: (playerFish) => {
// Tämä funktio kutsutaan, kun pelaajan kala törmää punaiseen kalaan
// Voit toteuttaa tässä vaikutuksen, jonka punainen kala aiheuttaa
// Esim. vähennä pelaajan elämiä tai lisää pelin nopeutta
console.log("Peli päättyi! Punainen kala osui pelaajan kalaa.");
gameOver = true;
},
},
// Lisää muut kalalajit ja niiden vaikutusfunktiot tarpeen mukaan
{
color: "yellow",
width: 37,
height: 24,
eye: { x: 11, y: -3, radius: 4},
pupil: { x: -1, y: 0, radius: 2},
onCollision: (fish) => { // NOTICE argumentti muutettu (playerFish -> fish)
console.log("Pelaaja sai pisteen!");
// NOTICE funktio kutsu lisätty
addPoints(1)
// Poista kala fishList-listalta
var fishIndex = fishList.indexOf(fish);
if (fishIndex !== -1) {
fishList.splice(fishIndex, 1);
}
},
},
{
color: "blue",
width: 26,
height: 26,
// NOTICE kupla ei tarvitse silmään liittyviä tietoja
// eye: { x: 15, y: 10, radius: 5 },
// pupil: { x: 16, y: 10, radius: 2 },
onCollision: (fish) => { // NOTICE argumentti muutettu (playerFish -> fish)
console.log("Pelaaja sai kolme pistettä kuplasta!");
// NOTICE funktio kutsu lisätty
addPoints(3)
// Poista kupla fishList-listalta
var fishIndex = fishList.indexOf(fish);
if (fishIndex !== -1) {
fishList.splice(fishIndex, 1);
}
},
// Arvotaan nopeus välillä 1-5
getSpeed: () => {
// NOTICE painotuksia muutettu
const speeds = [1.5, 1.0, 0.8];
const probabilities = [0.7, 0.2, 0.1];
// Arvotaan satunnainen indeksi painotetulla todennäköisyydellä
const random = Math.random();
let cumulativeProbability = 0;
for (let i = 0; i < speeds.length; i++) {
cumulativeProbability += probabilities[i];
if (random < cumulativeProbability) {
return speeds[i];
}
}
// Oletuksena palautetaan nopeus 1.2, jos kaikki todennäköisyydet ovat nollia
return 1.2;
},
},
];
// Luo uuden kalalistan, johon lisätään muut kalaobjektit
var fishList = [];
// NOTICE funktio lisätty ChatGPT'n viittauksen perusteella
function getVersion() {
return gameVersion
}
// Aloita peli
function startGame() {
// NOTICE Muuttujat on säästetty funktion edellisestä versiosta
fishList = [];
score = 0;
fishCount = 0; // Nollaa generoitujen kalojen määrä
// NOTICE lisätty nollauksia
gameDifficulty = 0;
maxFishCount = 5;
normalSpeed = 1;
time = 0
// Palauta pelaajan kalan position alkuperäiseen arvoon
playerFish.positionY = initialPlayerPosition;
// Päivitä pistemäärän näyttö
document.getElementById("score-display").textContent = score;
canvas.removeEventListener("click", startGame);
gameOver = false;
updateGame();
}
// Funktio, joka lisää pelaajalle pisteitä
function addPoints(points) {
score += points;
// Voit tässä päivittää myös näytöllä näkyvää pistetilannetta tarvittaessa
}
//
function getRandomColor() {
const colors = ["red", "yellow", "blue"];
// Muokkaa todennäköisyyslistaa vaikeustason perusteella
let probabilities;
if (gameDifficulty >= 4) {
const redProbability = 0.45 + (gameDifficulty - 4) * 0.02; // Punaisen todennäköisyys nousee 1-2% jokaisella vaikeustason nousulla
const yellowProbability = 0.45 - (gameDifficulty - 4) * 0.02; // Keltaisen todennäköisyys laskee 1-2% jokaisella vaikeustason nousulla
probabilities = [redProbability, yellowProbability, 0.1]; // Sininen pysyy samana (10%)
} else if (gameDifficulty >= 2) {
probabilities = [0.4, 0.45, 0.15]; // Punainen 40%, keltainen 45%, sininen 15%
} else if (gameDifficulty >= 1) {
probabilities = [0.35, 0.65, 0]; // Punainen 35%, keltainen 65%, sininen 0%
} else {
probabilities = [0.25, 0.75, 0]; // Punainen 25%, keltainen 75%, sininen 0%
}
// Arvotaan satunnainen indeksi painotetulla todennäköisyydellä
const random = Math.random();
let cumulativeProbability = 0;
for (let i = 0; i < colors.length; i++) {
cumulativeProbability += probabilities[i];
if (random < cumulativeProbability) {
// console.log(random + " - " + cumulativeProbability + " = " + colors[i] + " (" + i +")" + "(" + gameDifficulty +")")
return colors[i];
}
}
console.log("Kalaa ei arvottu? " + random)
// Oletuksena palautetaan sininen, jos kaikki todennäköisyydet ovat nollia (esim. vaikeustasolla 0)
return "yellow";
}
// NOTICE Joitakin osia tuotu vanhasta generaattorista
function generateFish() {
// Arvo satunnainen väri
const randomColor = getRandomColor()
// Etsi vastaava kala-objekti fishColorsData-listasta
const fishData = fishColorsData.find((fish) => fish.color === randomColor);
if (fishData) {
// Jos löydettiin kala-objekti, käytä getSpeed-funktiota tai arvo normaali nopeus
const speed = fishData.getSpeed ? fishData.getSpeed() : Math.random() < 0.12 ? 1.5 : 1; // getRandomNumber(1, 5);
// Generoidaan kalan sijainti ja muut ominaisuudet
const positionX = gameWidth;
//NOTICE Arvontaa muutettu kalan piirron muutoksen vuoksi + sijanti tiedot siirretty myöhemmälle kalojen vaihtelevan koon vuoksi
const positionY = Math.floor(Math.random() * (gameHeight - fishData.height) + fishData.height / 2); // Satunnainen korkeus (20-260); // Arvo satunnainen sijainti pystysuunnassa
const newFish = {
// DEBUG pidetään toistaiseksi kalan ominaisuutena
level: Math.floor(Math.random() * playerFish.level) + 1, // Satunnainen taso (1-pelaajan taso)
id: fishCount + 2, // Lisää 2 id:hen, jotta huomioi pelaajan kalan
color: fishData.color,
positionX,
positionY,
speed,
width: fishData.width,
height: fishData.height,
eye: { ...fishData.eye }, // Kopioidaan silmä-objekti uuteen kalahaamuun
pupil: { ...fishData.pupil }, // Kopioidaan pupilli-objekti uuteen kalahaamuun
onCollision: fishData.onCollision,
// Lisää muut kalan ominaisuudet tarpeen mukaan
};
fishList.push(newFish); // Lisää uusi kalaobjekti kalalistaan
fishCount++; // Kasvata generoitujen kalojen määrää yhdellä
} else {
console.log("Arvottua kalaa ei löytynyt!")
}
}
// Määritä pistemäärärajat eri vaikeustasoille
const difficultyThresholds = {
1: 10, // Esimerkki: 10 pistettä vaaditaan vaikeustason 1 saavuttamiseen
2: 25, // Esimerkki: 20 pistettä vaaditaan vaikeustason 2 saavuttamiseen
3: 40 // Esimerkki: 30 pistettä vaaditaan vaikeustason 3 saavuttamiseen
};
// Päivitä pelin vaikeustaso ja pelinopeus pelaajan pisteiden perusteella
function updateGameDifficulty(score) {
// Tarkista, onko saavutettu uusi vaikeustaso
for (const difficultyLevel in difficultyThresholds) {
if (score >= difficultyThresholds[difficultyLevel] && difficultyLevel > gameDifficulty) {
// Päivitä vaikeustaso ja pelinopeus
// NOTICE muuteettu nostamaan vaikeus tasoa
gameDifficulty += 1 // = parseInt(difficultyLevel);
normalSpeed += 0.5; // Esimerkki: Kasvata pelinopeutta 0.5 yksikköä uutta vaikeustasoa kohti
console.log(`Uusi vaikeustaso: ${gameDifficulty}`);
break; // Poistu silmukasta, kun ensimmäinen uusi vaikeustaso on löytynyt
}
}
}
function checkCollision_OLD(playerFish, fish) {
// Tarkista, osuvatko kalojen rajat toisiinsa
// NOTICE törmäys tarkastusta hienosäädetty
if (
// playerFish.positionX < fish.positionX + fish.width && // alkuperäinen
// NOTICE kalojen törmäystä säädetty
playerFish.positionX + playerFish.width / 2 < fish.positionX + fish.width / 2 &&
playerFish.positionX + playerFish.width > fish.positionX &&
playerFish.positionY < fish.positionY + fish.height &&
playerFish.positionY + playerFish.height > fish.positionY
) {
return true; // Osuvat yhteen
}
return false; // Eivät osu yhteen
}
function checkCollision(playerFish, fish) {
// Lasketaan kalojen keskipisteiden välinen etäisyys
// NOTICE laskentaa korjattu
const distanceX = (playerFish.positionX + playerFish.width - playerFish.height / 2) - (fish.positionX + fish.height/ 2);
const distanceY = (playerFish.positionY) - (fish.positionY);
const distance = Math.sqrt(distanceX ** 2 + distanceY ** 2);
// Lasketaan pelaajan ohjaaman kalan säde
const playerFishRadius = playerFish.height / 2;
// Lasketaan viholliskalan säde
const fishRadius = fish.height / 2;
// Tarkistetaan, osuvatko kalojen rajat toisiinsa
if (distance < playerFishRadius + fishRadius) {
return true; // Osuvat yhteen
}
return false; // Eivät osu yhteen
}
// Pelin päätyttyä tarkista tulosennätys
// NOTICE funktion nimi muutettu sekannuksen välttämiseksi
function updateGameOver() {
// NOTICE funktio kutsu muutettu muuttuja kutsuksi
const finalScore = score; // Oletetaan, että game.js-tiedostossa on metodi getScore() palauttamaan pelaajan pisteet
const highScore = checkHighScore(finalScore);
saveHighScore(highScore);
updateHighScoreElement();
// Muut pelin lopettamiseen liittyvät toimenpiteet...
}
// Päivittää pelitapahtumat ja liikuttaa kaloja
function updateGame() {
// Päivitä muut kalaobjektit
for (var i = 0; i < fishList.length; i++) {
var fish = fishList[i];
// NOTICE Kalan "fish.level" ominaisuus vaihdettu pelin perus nopeuteen "normalSpeed"
fish.positionX -= normalSpeed * fish.speed * 2;
// *** Lisätty ChatGPT'n luomaa koodia
// Tarkista, onko kala edennyt pelialueen reunan ohi
if (fish.positionX < -fish.width) {
// Poista kala listalta
fishList.splice(i, 1);
}
if (checkCollision(playerFish, fish)) {
console.log(fish)
fish.onCollision(fish); // Suoritetaan kalan "onCollision" -funktio törmäyksen tapahtuessa
// Tässä voit tehdä muutakin logiikkaa, jos tarpeen
document.getElementById("score-display").textContent = score;
}
}
// NOTICE funktio kutsu lisätty
renderGame(fishList, playerFish)
// NOTICE muuttuja viittausta muokattu vastaamaan aiempaa koodia
updateGameDifficulty(score);
// Generoi uusi kala satunnaisesti
// NOTICE generointi tiheyttä muutettu
if (Math.random() < 0.013) { // Voit säätää generointitiheyttä muuttamalla lukua
// && fishList.length < maxFishCount ChatGPT'n luomaa ominaisuutta ei vielä lisätty
generateFish();
}
// Tarkista, onko peli päättynyt
if (!gameOver) {
requestAnimationFrame(updateGame);
} else {
// NOTICE drawGameOver metodin paikkaa muutettu
drawGameOver();
updateGameOver()
}
time += 1 * normalSpeed;
}
function startMoving(direction) {
// Tarkista, että liike ei ole jo käynnissä
if (!movementInterval) {
movementInterval = setInterval(function () {
// Päivitä pelaajan kalan sijaintia haluttuun suuntaan
updatePlayerFishPosition(direction);
}, 10); // Päivitä liike pienellä aikavälillä (esim. 10 ms)
}
}
function stopMoving() {
// Pysäytä liike ja tyhjennä interval-muuttuja
clearInterval(movementInterval);
movementInterval = null;
}
document.addEventListener("keydown", function (event) {
// Tarkista, minkä nuolinäppäimen tapahtuma laukaisi
switch (event.keyCode) {
case 38: // Nuolinäppäin ylös
startMoving("up");
break;
case 40: // Nuolinäppäin alas
startMoving("down");
break;
}
});
document.addEventListener("keyup", function (event) {
// Tarkista, minkä nuolinäppäimen tapahtuma laukaisi
switch (event.keyCode) {
case 38: // Nuolinäppäin ylös
case 40: // Nuolinäppäin alas
stopMoving();
break;
}
});
// NOTICE Muutettu "playerFish.position" viittaus muotoon "playerFish.positionY"
function updatePlayerFishPosition(direction) {
// Päivitä pelaajan kalan sijaintia haluttuun suuntaan
if (direction === "up") {
playerFish.positionY -= playerFish.speed;
} else if (direction === "down") {
playerFish.positionY += playerFish.speed;
}
// Varmista, että pelaajan kala pysyy pelialueella
// NOTICE pelaajan kalan liikettä säädetty piirrossa tehdyn muutoksen vuoksi
if (playerFish.positionY < playerFish.height / 2) {
playerFish.positionY = playerFish.height / 2;
} else if (playerFish.positionY > gameHeight - playerFish.height / 2) {
playerFish.positionY = gameHeight - playerFish.height / 2;
}
}
// NOTICE lisätty funktio kutsut jo olemassa oleviin funktioigin
// Kuunnellaan napin painalluksia
document.getElementById('move-up').addEventListener('mousedown', function() {
// moveDirection = 1; // Pelaaja liikkuu ylös kun painetaan
startMoving("up");
});
document.getElementById('move-up').addEventListener('mouseup', function() {
// moveDirection = 0; // Pelaaja pysähtyy kun päästetään nappi
stopMoving();
});
document.getElementById('move-down').addEventListener('mousedown', function() {
// moveDirection = -1; // Pelaaja liikkuu alas kun painetaan
startMoving("down");
});
document.getElementById('move-down').addEventListener('mouseup', function() {
// moveDirection = 0; // Pelaaja pysähtyy kun päästetään nappi
stopMoving();
});
// Tämä lisää tapahtumakuuntelijan "touchstart" -tapahtumalle, joka toimii mobiililaitteilla
document.getElementById('move-up').addEventListener('touchstart', () => {
startMoving("up");
});
// Tämä lisää tapahtumakuuntelijan "touchstart" -tapahtumalle, joka toimii mobiililaitteilla
document.getElementById('move-down').addEventListener('touchstart', () => {
startMoving("down");
});
// Tämä lisää tapahtumakuuntelijan "touchstart" -tapahtumalle, joka toimii mobiililaitteilla
document.getElementById('move-up').addEventListener('touchend', () => {
stopMoving();
});
// Tämä lisää tapahtumakuuntelijan "touchstart" -tapahtumalle, joka toimii mobiililaitteilla
document.getElementById('move-down').addEventListener('touchsend', () => {
stopMoving();
});
// Kutsu drawGameOver-funktiota pelin alussa
// NOTICE "updateHighScore" -funktio kutsu lisätty
updateHighScoreElement()
drawStartGame();
JavaScript:
// NOTICE siirretty game.js tiedostosta
var canvas = document.getElementById("game-canvas");
var ctx = canvas.getContext("2d");
var gameWidth = canvas.width;
var gameHeight = canvas.height;
function drawBackground(ctx, canvasWidth, canvasHeight) {
// Luodaan sinisen liukuvärin alkaen pohjasta (tummempi) ja päättyen yläosaan (vaaleampi)
const gradient = ctx.createLinearGradient(0, gameHeight, 0, 0);
gradient.addColorStop(0, "#003366"); // Tumma sininen
gradient.addColorStop(1, "#66ccff"); // Vaalea sininen
// Piirretään liukuväri taustalle
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, gameWidth, gameHeight);
// Piirrä pohjan hiekanvärisen alueen alareuna
// NOTICE "context" muuttuja viittaukset vaihdettu muotoon "ctx"
// ctx.fillStyle = "sandybrown";
// ctx.fillRect(0, gameHeight - 10, gameWidth, 10);
drawSand3(time)
// NOTICE lisätty viittaus funktioon
drawGameVersion();
}
// NOTICE parametrit muutettu
function drawSand3(time = 0) {
const sandHeight = gameHeight * 0.12; // Voit muuttaa hiekkapohjan korkeutta täällä
const sandWidth = gameWidth * 1.2; // Muuta tätä arvoa tarvittaessa
// Luodaan liukuvärjätty alue
const gradient = ctx.createLinearGradient(0, gameHeight, 0, gameHeight - sandHeight);
gradient.addColorStop(0, "SaddleBrown"); // Yläreuna väri (sandybrown)
gradient.addColorStop(1, "sandybrown"); // Alareuna väri (white)
// Piirrä liukuvärjätty alue
ctx.fillStyle = gradient;
ctx.fillRect(0, gameHeight - sandHeight, gameWidth, sandHeight);
// Piirrä liukuvärjätty alue
ctx.fillStyle = gradient;
ctx.fillRect(-sandWidth / 2, gameHeight - sandHeight, sandWidth, sandHeight);
// Aaltoileva yläreuna
const waveHeight = 5;
const waveLength = 100;
const yOffset = 2 * Math.sin(time / 100);
ctx.beginPath();
ctx.moveTo(-sandWidth / 2, gameHeight - sandHeight);
for (let x = -sandWidth / 2; x < gameWidth + sandWidth / 2; x += 10) {
const y = gameHeight - sandHeight + waveHeight * Math.sin((x + time) / waveLength) + yOffset;
ctx.lineTo(x, y);
}
ctx.lineTo(gameWidth + sandWidth / 2, gameHeight - sandHeight);
ctx.closePath();
ctx.fillStyle = "peru"; // (sandybrown) -> (Chocolate)
ctx.fill();
}
// NOTICE pelin versionumeron piirtämisestä tehty funktio
// NOTICE piirtämistä fixattu hieman, väri, fontti koko ja kohta
// NOTICE "context" muuttuja viittaukset vaihdettu muotoon "ctx"
function drawGameVersion() {
// Piirrä pelin versionumero
const version = getVersion(); // Oletetaan, että game.js-tiedostossa on metodi getVersion() palauttamaan versionumeron
ctx.fillStyle = "Black";
ctx.font = "10px Arial";
ctx.fillText(version, gameWidth - 20, 10);
}
// NOTICE drawGameStart ja drawGameOver funktiot siirretty game.js -tiedostosta
// *** Lisätty ChatGPT'n luomaa koodia
// Piirrä "Aloita peli" -nappi
function drawStartGame() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // Tyhjennä canvas
ctx.fillStyle = "#4CAF50";
ctx.fillRect(canvas.width / 2 - 80, canvas.height / 2 - 25, 160, 50);
ctx.font = "20px Arial";
ctx.fillStyle = "white";
ctx.textAlign = "center";
ctx.fillText("Aloita peli", canvas.width / 2, canvas.height / 2 + 8);
canvas.addEventListener("click", startGame);
}
// Piirrä "Peli loppui" -viesti ja "Aloita peli" -nappi
function drawGameOver() {
ctx.save(); // Tallenna piirtotila
ctx.globalAlpha = 0.5; // Aseta läpinäkyvyys
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalAlpha = 1; // Palauta täysi läpinäkyvyys
ctx.font = "30px Arial";
ctx.fillStyle = "white";
ctx.textAlign = "center";
ctx.fillText("Peli loppui!", canvas.width / 2, canvas.height / 2 - 20);
ctx.fillStyle = "#4CAF50";
ctx.fillRect(canvas.width / 2 - 80, canvas.height / 2 + 10, 160, 50);
ctx.font = "20px Arial";
ctx.fillStyle = "white";
ctx.fillText("Aloita peli", canvas.width / 2, canvas.height / 2 + 40);
ctx.restore(); // Palauta piirtotila
canvas.addEventListener("click", startGame);
}
// NOTICE "playerFish" muuttuja viittaukset muutettu "fish" -muotoon, kuten muissakin kaloissa
function drawPlayerFish(fish) {
ctx.fillStyle = playerFish.color; // Aseta pelaajan kalan väri (esim. oranssi)
// Pyrstö
ctx.beginPath();
ctx.arc(fish.positionX, fish.positionY, fish.height / 2, Math.PI / 2 , Math.PI + Math.PI / 2, true);
ctx.closePath();
ctx.fill();
// Lasketaan etäisyys keskeltä kärkeen
const sideLength = 14 // (fish.height / 2) / Math.cos(Math.PI / 6);
ctx.beginPath();
ctx.moveTo(fish.positionX + fish.width - fish.height / 2, fish.positionY - fish.height / 2);
ctx.arc(fish.positionX + fish.width - fish.height / 2, fish.positionY, fish.height / 2, Math.PI * 1.5, Math.PI * 0.5, false);
// NOTICE lisätty
ctx.lineTo(fish.positionX + fish.width - sideLength - sideLength / 2, fish.positionY + fish.height / 2);
ctx.arc(fish.positionX + fish.width - sideLength - sideLength / 2, fish.positionY, fish.height / 2, Math.PI * 0.5, Math.PI * 1.5, false);
ctx.closePath();
ctx.fill();
// Piirrä silmä
ctx.fillStyle = "white"; // Silmän väri
ctx.beginPath();
ctx.arc(
fish.positionX + fish.eye.x,
fish.positionY + fish.eye.y,
fish.eye.radius,
0,
2 * Math.PI
);
ctx.fill();
// Piirrä pupilli
ctx.fillStyle = "black"; // Pupillin väri
ctx.beginPath();
ctx.arc(
fish.positionX + fish.eye.x + fish.pupil.x,
fish.positionY + fish.eye.y + fish.pupil.y,
fish.pupil.radius,
0,
2 * Math.PI
);
ctx.fill();
}
function drawRedFish(fish) {
ctx.fillStyle = "red";
// Pyrstö
ctx.beginPath();
ctx.moveTo(fish.positionX + fish.width, fish.positionY - fish.height / 2);
ctx.lineTo(fish.positionX + fish.width - fish.height * 0.6, fish.positionY);
ctx.lineTo(fish.positionX + fish.width, fish.positionY + fish.height / 2)
ctx.closePath();
ctx.fill();
// Kala
let cornerRadius = 12;
ctx.beginPath();
ctx.moveTo(fish.positionX + cornerRadius, fish.positionY - fish.height / 2);
ctx.arcTo(fish.positionX, fish.positionY - fish.height / 2, fish.positionX, fish.positionY + cornerRadius, cornerRadius);
ctx.lineTo(fish.positionX, fish.positionY + fish.height / 2 - cornerRadius);
ctx.arcTo(fish.positionX, fish.positionY + fish.height / 2, fish.positionX + cornerRadius, fish.positionY + fish.height / 2, cornerRadius);
ctx.lineTo(fish.positionX + cornerRadius + 15, fish.positionY + fish.height / 2);
//ctx.lineTo(x + width, y);
// NOTICE lisätty puoli pyöreä takaosa
// ctx.arcTo(fish.positionX + cornerRadius * 2 + 15, fish.positionY + fish.height, fish.positionX + cornerRadius * 3 + 15, fish.positionY + fish.height / 2, fish.height / 2);
// ctx.arcTo(fish.positionX + cornerRadius * 3 + 15, fish.positionY, fish.positionX + cornerRadius * 2 + 15 , fish.positionY, fish.height / 2);
ctx.arc(fish.positionX + cornerRadius + 15, fish.positionY, fish.height / 2, Math.PI * 1.5, Math.PI * 0.5, false);
ctx.lineTo(fish.positionX + cornerRadius + 15, fish.positionY - fish.height / 2);
ctx.closePath();
ctx.fill();
// Piirrä silmä
ctx.fillStyle = "hotpink"; // Silmän väri
ctx.beginPath();
ctx.arc(
fish.positionX + fish.eye.x,
fish.positionY + fish.eye.y,
fish.eye.radius,
0,
2 * Math.PI
);
ctx.fill();
// Piirrä pupilli
ctx.fillStyle = "black"; // Pupillin väri
ctx.beginPath();
ctx.arc(
fish.positionX + fish.eye.x + fish.pupil.x,
fish.positionY + fish.eye.y + fish.pupil.y,
fish.pupil.radius,
0,
2 * Math.PI
);
ctx.fill();
}
function drawYellowFish(fish) {
ctx.fillStyle = "yellow";
// Pyrstö
ctx.beginPath();
ctx.arc(fish.positionX + fish.width, fish.positionY, fish.height / 2, Math.PI / 2 , Math.PI + Math.PI / 2, false);
ctx.closePath();
ctx.fill();
// Kala
// Lasketaan etäisyys keskeltä kärkeen
const side = (fish.height / 2) / Math.cos(Math.PI / 6);
// console.log(side); // Tulostaa etäisyyden keskeltä kärkeen
const sideLength = (fish.height / 2) / Math.cos(Math.PI / 6);
ctx.beginPath();
ctx.moveTo(fish.positionX + sideLength / 2, fish.positionY - fish.height / 2);
ctx.lineTo(fish.positionX + sideLength + sideLength / 2, fish.positionY - fish.height / 2);
ctx.lineTo(fish.positionX + sideLength * 2, fish.positionY);
ctx.lineTo(fish.positionX + sideLength + sideLength / 2, fish.positionY + fish.height / 2);
ctx.lineTo(fish.positionX + sideLength / 2, fish.positionY + fish.height / 2);
ctx.lineTo(fish.positionX, fish.positionY);
ctx.closePath();
ctx.fill();
// Piirrä silmä
ctx.fillStyle = "white"; // Silmän väri
ctx.beginPath();
ctx.arc(
fish.positionX + fish.eye.x,
fish.positionY + fish.eye.y,
fish.eye.radius,
0,
2 * Math.PI
);
ctx.fill();
// Piirrä pupilli
ctx.fillStyle = "black"; // Pupillin väri
ctx.beginPath();
ctx.arc(
fish.positionX + fish.eye.x + fish.pupil.x,
fish.positionY + fish.eye.y + fish.pupil.y,
fish.pupil.radius,
0,
2 * Math.PI
);
ctx.fill();
}
// NOTICE "ctx" -parametri poistettu
function drawBubble(bubble) {
ctx.fillStyle = "blue";
ctx.beginPath();
ctx.arc(
// bubble.positionX + (bubble.width / 4), // piirretään kupla hieman eteen sijainnista, osumisen parantamisen vuoksi
bubble.positionX,
// bubble.positionY + bubble.height / 2, // NOTICE kupla siirretty korkeus suunnasssa (jotta törmäys voidaan laskea oikein)
bubble.positionY,
// NOTICE "radius" ominaisuus muutettu "height" muotoon
bubble.height / 2,
0,
Math.PI * 2,
false
);
ctx.closePath();
ctx.fill();
}
// NOTICE kalan ominaisuus "type" muutettu muotoon "color"
function drawFishList(fishList) {
fishList.forEach((fish) => {
if (fish.color === "red") {
drawRedFish(fish);
} else if (fish.color === "yellow") {
drawYellowFish(fish);
// NOTICE muutettu vastaamaan "fish" objektissa olevaa väriä
} else if (fish.color === "blue") {
drawBubble(fish);
}
});
}
// ***
function drawFish(fish){
// Piirrä kala
ctx.fillStyle = fish.color;
// NOTICE kalan kokoa muutettu
ctx.fillRect(canvas.width - fish.position, fish.height, 50, 30);
}
// *** Lisätty ChatGPT'n luomaa koodia
// Piirtämiseen liittyvä funktio
function renderGame(fishList, playerFish) {
// Tyhjennä canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Piirrä pelialueen tausta
// NOTICE funktiokutsu lisätty
drawBackground(ctx, gameWidth, gameHeight)
// Piirrä kalat
drawFishList(fishList); // Piirrä kaikki kalat
// Piirrä pelaajan ohjaama kala
drawPlayerFish(playerFish);
// Piirrä muut tarvittavat visuaaliset elementi
}
Pelissä on toki muitakin kehityskohtia, myös niitä saa ja kannattaa tuoda esille.
edit. pelin koodit liitetty viestiin.
Viimeksi muokattu: