/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Arrow = Container.expand(function () { var self = Container.call(this); var arrowBody = self.attachAsset('arrow', { anchorX: 0, anchorY: 0.5 }); var arrowHead = self.attachAsset('arrowHead', { anchorX: 0, anchorY: 0.5, x: 120 }); self.velocityX = 0; self.velocityY = 0; self.gravity = 0.3; self.isFlying = false; self.update = function () { if (self.isFlying) { self.x += self.velocityX; self.y += self.velocityY; self.velocityY += self.gravity; // Update rotation based on velocity self.rotation = Math.atan2(self.velocityY, self.velocityX); // Check if arrow is off screen if (self.x > 6600 || self.y > 8400) { self.isFlying = false; self.destroy(); } } }; self.fire = function (power, angle) { var speed = power * 45; self.velocityX = Math.cos(angle) * speed; self.velocityY = Math.sin(angle) * speed; self.isFlying = true; self.rotation = angle; }; return self; }); var Bow = Container.expand(function () { var self = Container.call(this); var bowBody = self.attachAsset('Bow', { anchorX: 0.5, anchorY: 0.5 }); self.isPulling = false; self.pullDistance = 0; self.maxPull = 150; return self; }); var Target = Container.expand(function () { var self = Container.call(this); var bullseye = self.attachAsset('bullseye', { anchorX: 0.5, anchorY: 0.5 }); self.getScore = function (hitX, hitY) { var dx = hitX - self.x; var dy = hitY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= 40) { return 10; } // Bullseye if (distance <= 200) { return 5; } // Target hit return 0; // Miss }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Define bow and target positions for each level var bowPositions = [{ x: 300, y: 2400 }, // Level 1 { x: 200, y: 2000 }, // Level 2 { x: 400, y: 2500 }, // Level 3 { x: 150, y: 1800 }, // Level 4 { x: 500, y: 2200 }, // Level 5 { x: 100, y: 2500 }, // Level 6 { x: 350, y: 1900 }, // Level 7 { x: 250, y: 2600 }, // Level 8 { x: 450, y: 2100 }, // Level 9 { x: 180, y: 2300 }, // Level 10 { x: 320, y: 2550 }, // Level 11 { x: 120, y: 1950 }, // Level 12 { x: 380, y: 2450 }, // Level 13 { x: 280, y: 2150 }, // Level 14 { x: 420, y: 2350 }, // Level 15 { x: 160, y: 2650 }, // Level 16 { x: 340, y: 1850 }, // Level 17 { x: 220, y: 2650 }, // Level 18 { x: 480, y: 2050 }, // Level 19 { x: 140, y: 2400 }, // Level 20 { x: 360, y: 2600 }, // Level 21 { x: 260, y: 1950 }, // Level 22 { x: 440, y: 2250 }, // Level 23 { x: 190, y: 2500 }, // Level 24 { x: 300, y: 2400 } // Level 25 ]; var targetPositions = [{ x: 1648, y: 400 }, // Level 1 { x: 1600, y: 600 }, // Level 2 { x: 1700, y: 400 }, // Level 3 { x: 1700, y: 800 }, // Level 4 { x: 1550, y: 500 }, // Level 5 { x: 1748, y: 450 }, // Level 6 { x: 1650, y: 700 }, // Level 7 { x: 1750, y: 400 }, // Level 8 { x: 1500, y: 650 }, // Level 9 { x: 1800, y: 550 }, // Level 10 { x: 1600, y: 450 }, // Level 11 { x: 1800, y: 750 }, // Level 12 { x: 1450, y: 400 }, // Level 13 { x: 1848, y: 600 }, // Level 14 { x: 1700, y: 400 }, // Level 15 { x: 1550, y: 800 }, // Level 16 { x: 1748, y: 400 }, // Level 17 { x: 1650, y: 650 }, // Level 18 { x: 1750, y: 500 }, // Level 19 { x: 1500, y: 400 }, // Level 20 { x: 1800, y: 700 }, // Level 21 { x: 1600, y: 400 }, // Level 22 { x: 1800, y: 600 }, // Level 23 { x: 1450, y: 450 }, // Level 24 { x: 1648, y: 400 } // Level 25 ]; var target = game.addChild(new Target()); target.x = targetPositions[0].x; target.y = targetPositions[0].y; var bow = game.addChild(new Bow()); bow.x = bowPositions[0].x; bow.y = bowPositions[0].y; var arrows = []; var currentArrow = null; var isDragging = false; var dragStartX = 0; var dragStartY = 0; var pullDistance = 0; var arrowsRemaining = 3; var trajectoryLine = null; var currentLevel = 1; // Level display var levelTxt = new Text2('Level: 1', { size: 80, fill: 0xFFFFFF }); levelTxt.anchor.set(0.5, 0); LK.gui.top.addChild(levelTxt); // Arrows remaining display var arrowsTxt = new Text2('Arrows: 3', { size: 60, fill: 0xFFFFFF }); arrowsTxt.anchor.set(1, 0); arrowsTxt.x = -50; arrowsTxt.y = 100; LK.gui.topRight.addChild(arrowsTxt); function createNewArrow() { if (currentArrow) { currentArrow.destroy(); } currentArrow = game.addChild(new Arrow()); currentArrow.x = bow.x; currentArrow.y = bow.y; currentArrow.rotation = 0; currentArrow.alpha = 0.8; } function updateLevel() { levelTxt.setText('Level: ' + currentLevel); } function updateArrowsDisplay() { arrowsTxt.setText('Arrows: ' + arrowsRemaining); } function nextLevel() { currentLevel++; updateLevel(); // Clear ALL arrows from previous level (including stuck arrows) for (var i = arrows.length - 1; i >= 0; i--) { arrows[i].destroy(); } arrows = []; // Clear any arrows that might be stuck in target or remaining on screen var allArrows = game.children.filter(function (child) { return child instanceof Arrow; }); for (var j = allArrows.length - 1; j >= 0; j--) { allArrows[j].destroy(); } arrowsRemaining = 3; updateArrowsDisplay(); targetHit = false; // Clear current arrow if it exists if (currentArrow) { currentArrow.destroy(); currentArrow = null; } // Clear trajectory line if it exists if (trajectoryLine) { trajectoryLine.destroy(); trajectoryLine = null; } // Update bow and target positions for new level if (currentLevel <= 25) { var levelIndex = currentLevel - 1; bow.x = bowPositions[levelIndex].x; bow.y = bowPositions[levelIndex].y; target.x = targetPositions[levelIndex].x; target.y = targetPositions[levelIndex].y; } // Create new arrow createNewArrow(); } // Initialize first arrow createNewArrow(); var targetHit = false; game.down = function (x, y, obj) { if (currentArrow && arrowsRemaining > 0 && !targetHit) { isDragging = true; dragStartX = x; dragStartY = y; // Create trajectory line trajectoryLine = new Container(); game.addChild(trajectoryLine); } }; game.move = function (x, y, obj) { if (isDragging && currentArrow) { var dx = dragStartX - x; var dy = dragStartY - y; pullDistance = Math.sqrt(dx * dx + dy * dy); if (pullDistance > 200) { pullDistance = 200; var angle = Math.atan2(dy, dx); dx = Math.cos(angle) * 200; dy = Math.sin(angle) * 200; } // Update arrow position and rotation based on pull var angle = Math.atan2(dy, dx); currentArrow.x = bow.x - dx * 0.3; currentArrow.y = bow.y - dy * 0.3; currentArrow.rotation = angle; // Set bow rotation to match arrow angle during pull bow.rotation = angle; // Visual feedback for pull strength var pullStrength = pullDistance / 200; currentArrow.alpha = 0.5 + pullStrength * 0.5; // Update trajectory line if (trajectoryLine) { // Clear previous dots while (trajectoryLine.children.length > 0) { trajectoryLine.children[0].destroy(); } // Calculate trajectory if (pullDistance > 20) { var power = Math.min(pullDistance / 200, 1); var speed = power * 45; var vx = Math.cos(angle) * speed; var vy = Math.sin(angle) * speed; var gravity = 0.3; // Draw trajectory dots for (var t = 0; t < 50; t++) { var dotX = currentArrow.x + vx * t; var dotY = currentArrow.y + vy * t + 0.5 * gravity * t * t; // Stop if dot goes off screen if (dotX > 2048 || dotY > 2732) { break; } var dot = trajectoryLine.attachAsset('trajectoryDot', { anchorX: 0.5, anchorY: 0.5, x: dotX - trajectoryLine.x, y: dotY - trajectoryLine.y, alpha: 0.4 - t * 0.008 }); } } } } }; game.up = function (x, y, obj) { if (isDragging && currentArrow && arrowsRemaining > 0) { isDragging = false; // Clear trajectory line if (trajectoryLine) { trajectoryLine.destroy(); trajectoryLine = null; } if (pullDistance > 20) { // Fire the arrow var dx = dragStartX - x; var dy = dragStartY - y; var angle = Math.atan2(dy, dx); var power = Math.min(pullDistance / 200, 1); currentArrow.fire(power, angle); arrows.push(currentArrow); arrowsRemaining--; updateArrowsDisplay(); LK.getSound('shoot').play(); currentArrow = null; // Create new arrow after a delay LK.setTimeout(function () { if (arrowsRemaining > 0) { createNewArrow(); } }, 200); } else { // Reset arrow position if pull was too weak currentArrow.x = bow.x; currentArrow.y = bow.y; currentArrow.rotation = 0; currentArrow.alpha = 0.8; } pullDistance = 0; // Reset bow rotation when releasing bow.rotation = 0; } }; game.update = function () { // Check arrow collisions with bullseye only for (var i = arrows.length - 1; i >= 0; i--) { var arrow = arrows[i]; if (arrow.isFlying) { // Calculate arrowhead position (arrowhead is at x+120 from arrow body) var arrowheadX = arrow.x + Math.cos(arrow.rotation) * 120; var arrowheadY = arrow.y + Math.sin(arrow.rotation) * 120; // Check if arrowhead specifically hits bullseye (using actual bullseye asset size) var dx = arrowheadX - target.x; var dy = arrowheadY - target.y; var distance = Math.sqrt(dx * dx + dy * dy); // Use half the bullseye width as the hit radius (82.14 pixels) var bullseyeRadius = 164.28 / 2; var isBullseyeHit = distance <= bullseyeRadius; // Only trigger if hitting bullseye if (isBullseyeHit) { // Arrow hit bullseye arrow.isFlying = false; arrow.velocityX = 0; arrow.velocityY = 0; targetHit = true; LK.effects.flashObject(target, 0x00FF00, 500); LK.getSound('hit').play(); // Show level complete popup var levelPopup = new Text2('Level Complete!', { size: 100, fill: 0xFFD700 }); levelPopup.anchor.set(0.5, 0.5); levelPopup.x = arrow.x; levelPopup.y = arrow.y - 50; game.addChild(levelPopup); tween(levelPopup, { y: levelPopup.y - 100, alpha: 0 }, { duration: 2000, onFinish: function onFinish() { levelPopup.destroy(); nextLevel(); } }); arrows.splice(i, 1); } } } // Check win condition (completing level 25) if (currentLevel > 25) { LK.showYouWin(); } // Check game over condition - if no arrows left and no arrow in flight if (arrowsRemaining <= 0 && arrows.length === 0 && !currentArrow && currentLevel <= 25) { LK.setTimeout(function () { LK.showGameOver(); }, 2000); } // Check if arrows remaining is 0 but target is not hit, end the game if (arrowsRemaining === 0 && !currentArrow && !targetHit) { var anyArrowFlying = false; for (var j = 0; j < arrows.length; j++) { if (arrows[j].isFlying) { anyArrowFlying = true; break; } } if (!anyArrowFlying) { LK.setTimeout(function () { LK.showGameOver(); }, 1000); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Arrow = Container.expand(function () {
var self = Container.call(this);
var arrowBody = self.attachAsset('arrow', {
anchorX: 0,
anchorY: 0.5
});
var arrowHead = self.attachAsset('arrowHead', {
anchorX: 0,
anchorY: 0.5,
x: 120
});
self.velocityX = 0;
self.velocityY = 0;
self.gravity = 0.3;
self.isFlying = false;
self.update = function () {
if (self.isFlying) {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
// Update rotation based on velocity
self.rotation = Math.atan2(self.velocityY, self.velocityX);
// Check if arrow is off screen
if (self.x > 6600 || self.y > 8400) {
self.isFlying = false;
self.destroy();
}
}
};
self.fire = function (power, angle) {
var speed = power * 45;
self.velocityX = Math.cos(angle) * speed;
self.velocityY = Math.sin(angle) * speed;
self.isFlying = true;
self.rotation = angle;
};
return self;
});
var Bow = Container.expand(function () {
var self = Container.call(this);
var bowBody = self.attachAsset('Bow', {
anchorX: 0.5,
anchorY: 0.5
});
self.isPulling = false;
self.pullDistance = 0;
self.maxPull = 150;
return self;
});
var Target = Container.expand(function () {
var self = Container.call(this);
var bullseye = self.attachAsset('bullseye', {
anchorX: 0.5,
anchorY: 0.5
});
self.getScore = function (hitX, hitY) {
var dx = hitX - self.x;
var dy = hitY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= 40) {
return 10;
} // Bullseye
if (distance <= 200) {
return 5;
} // Target hit
return 0; // Miss
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Define bow and target positions for each level
var bowPositions = [{
x: 300,
y: 2400
},
// Level 1
{
x: 200,
y: 2000
},
// Level 2
{
x: 400,
y: 2500
},
// Level 3
{
x: 150,
y: 1800
},
// Level 4
{
x: 500,
y: 2200
},
// Level 5
{
x: 100,
y: 2500
},
// Level 6
{
x: 350,
y: 1900
},
// Level 7
{
x: 250,
y: 2600
},
// Level 8
{
x: 450,
y: 2100
},
// Level 9
{
x: 180,
y: 2300
},
// Level 10
{
x: 320,
y: 2550
},
// Level 11
{
x: 120,
y: 1950
},
// Level 12
{
x: 380,
y: 2450
},
// Level 13
{
x: 280,
y: 2150
},
// Level 14
{
x: 420,
y: 2350
},
// Level 15
{
x: 160,
y: 2650
},
// Level 16
{
x: 340,
y: 1850
},
// Level 17
{
x: 220,
y: 2650
},
// Level 18
{
x: 480,
y: 2050
},
// Level 19
{
x: 140,
y: 2400
},
// Level 20
{
x: 360,
y: 2600
},
// Level 21
{
x: 260,
y: 1950
},
// Level 22
{
x: 440,
y: 2250
},
// Level 23
{
x: 190,
y: 2500
},
// Level 24
{
x: 300,
y: 2400
} // Level 25
];
var targetPositions = [{
x: 1648,
y: 400
},
// Level 1
{
x: 1600,
y: 600
},
// Level 2
{
x: 1700,
y: 400
},
// Level 3
{
x: 1700,
y: 800
},
// Level 4
{
x: 1550,
y: 500
},
// Level 5
{
x: 1748,
y: 450
},
// Level 6
{
x: 1650,
y: 700
},
// Level 7
{
x: 1750,
y: 400
},
// Level 8
{
x: 1500,
y: 650
},
// Level 9
{
x: 1800,
y: 550
},
// Level 10
{
x: 1600,
y: 450
},
// Level 11
{
x: 1800,
y: 750
},
// Level 12
{
x: 1450,
y: 400
},
// Level 13
{
x: 1848,
y: 600
},
// Level 14
{
x: 1700,
y: 400
},
// Level 15
{
x: 1550,
y: 800
},
// Level 16
{
x: 1748,
y: 400
},
// Level 17
{
x: 1650,
y: 650
},
// Level 18
{
x: 1750,
y: 500
},
// Level 19
{
x: 1500,
y: 400
},
// Level 20
{
x: 1800,
y: 700
},
// Level 21
{
x: 1600,
y: 400
},
// Level 22
{
x: 1800,
y: 600
},
// Level 23
{
x: 1450,
y: 450
},
// Level 24
{
x: 1648,
y: 400
} // Level 25
];
var target = game.addChild(new Target());
target.x = targetPositions[0].x;
target.y = targetPositions[0].y;
var bow = game.addChild(new Bow());
bow.x = bowPositions[0].x;
bow.y = bowPositions[0].y;
var arrows = [];
var currentArrow = null;
var isDragging = false;
var dragStartX = 0;
var dragStartY = 0;
var pullDistance = 0;
var arrowsRemaining = 3;
var trajectoryLine = null;
var currentLevel = 1;
// Level display
var levelTxt = new Text2('Level: 1', {
size: 80,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(levelTxt);
// Arrows remaining display
var arrowsTxt = new Text2('Arrows: 3', {
size: 60,
fill: 0xFFFFFF
});
arrowsTxt.anchor.set(1, 0);
arrowsTxt.x = -50;
arrowsTxt.y = 100;
LK.gui.topRight.addChild(arrowsTxt);
function createNewArrow() {
if (currentArrow) {
currentArrow.destroy();
}
currentArrow = game.addChild(new Arrow());
currentArrow.x = bow.x;
currentArrow.y = bow.y;
currentArrow.rotation = 0;
currentArrow.alpha = 0.8;
}
function updateLevel() {
levelTxt.setText('Level: ' + currentLevel);
}
function updateArrowsDisplay() {
arrowsTxt.setText('Arrows: ' + arrowsRemaining);
}
function nextLevel() {
currentLevel++;
updateLevel();
// Clear ALL arrows from previous level (including stuck arrows)
for (var i = arrows.length - 1; i >= 0; i--) {
arrows[i].destroy();
}
arrows = [];
// Clear any arrows that might be stuck in target or remaining on screen
var allArrows = game.children.filter(function (child) {
return child instanceof Arrow;
});
for (var j = allArrows.length - 1; j >= 0; j--) {
allArrows[j].destroy();
}
arrowsRemaining = 3;
updateArrowsDisplay();
targetHit = false;
// Clear current arrow if it exists
if (currentArrow) {
currentArrow.destroy();
currentArrow = null;
}
// Clear trajectory line if it exists
if (trajectoryLine) {
trajectoryLine.destroy();
trajectoryLine = null;
}
// Update bow and target positions for new level
if (currentLevel <= 25) {
var levelIndex = currentLevel - 1;
bow.x = bowPositions[levelIndex].x;
bow.y = bowPositions[levelIndex].y;
target.x = targetPositions[levelIndex].x;
target.y = targetPositions[levelIndex].y;
}
// Create new arrow
createNewArrow();
}
// Initialize first arrow
createNewArrow();
var targetHit = false;
game.down = function (x, y, obj) {
if (currentArrow && arrowsRemaining > 0 && !targetHit) {
isDragging = true;
dragStartX = x;
dragStartY = y;
// Create trajectory line
trajectoryLine = new Container();
game.addChild(trajectoryLine);
}
};
game.move = function (x, y, obj) {
if (isDragging && currentArrow) {
var dx = dragStartX - x;
var dy = dragStartY - y;
pullDistance = Math.sqrt(dx * dx + dy * dy);
if (pullDistance > 200) {
pullDistance = 200;
var angle = Math.atan2(dy, dx);
dx = Math.cos(angle) * 200;
dy = Math.sin(angle) * 200;
}
// Update arrow position and rotation based on pull
var angle = Math.atan2(dy, dx);
currentArrow.x = bow.x - dx * 0.3;
currentArrow.y = bow.y - dy * 0.3;
currentArrow.rotation = angle;
// Set bow rotation to match arrow angle during pull
bow.rotation = angle;
// Visual feedback for pull strength
var pullStrength = pullDistance / 200;
currentArrow.alpha = 0.5 + pullStrength * 0.5;
// Update trajectory line
if (trajectoryLine) {
// Clear previous dots
while (trajectoryLine.children.length > 0) {
trajectoryLine.children[0].destroy();
}
// Calculate trajectory
if (pullDistance > 20) {
var power = Math.min(pullDistance / 200, 1);
var speed = power * 45;
var vx = Math.cos(angle) * speed;
var vy = Math.sin(angle) * speed;
var gravity = 0.3;
// Draw trajectory dots
for (var t = 0; t < 50; t++) {
var dotX = currentArrow.x + vx * t;
var dotY = currentArrow.y + vy * t + 0.5 * gravity * t * t;
// Stop if dot goes off screen
if (dotX > 2048 || dotY > 2732) {
break;
}
var dot = trajectoryLine.attachAsset('trajectoryDot', {
anchorX: 0.5,
anchorY: 0.5,
x: dotX - trajectoryLine.x,
y: dotY - trajectoryLine.y,
alpha: 0.4 - t * 0.008
});
}
}
}
}
};
game.up = function (x, y, obj) {
if (isDragging && currentArrow && arrowsRemaining > 0) {
isDragging = false;
// Clear trajectory line
if (trajectoryLine) {
trajectoryLine.destroy();
trajectoryLine = null;
}
if (pullDistance > 20) {
// Fire the arrow
var dx = dragStartX - x;
var dy = dragStartY - y;
var angle = Math.atan2(dy, dx);
var power = Math.min(pullDistance / 200, 1);
currentArrow.fire(power, angle);
arrows.push(currentArrow);
arrowsRemaining--;
updateArrowsDisplay();
LK.getSound('shoot').play();
currentArrow = null;
// Create new arrow after a delay
LK.setTimeout(function () {
if (arrowsRemaining > 0) {
createNewArrow();
}
}, 200);
} else {
// Reset arrow position if pull was too weak
currentArrow.x = bow.x;
currentArrow.y = bow.y;
currentArrow.rotation = 0;
currentArrow.alpha = 0.8;
}
pullDistance = 0;
// Reset bow rotation when releasing
bow.rotation = 0;
}
};
game.update = function () {
// Check arrow collisions with bullseye only
for (var i = arrows.length - 1; i >= 0; i--) {
var arrow = arrows[i];
if (arrow.isFlying) {
// Calculate arrowhead position (arrowhead is at x+120 from arrow body)
var arrowheadX = arrow.x + Math.cos(arrow.rotation) * 120;
var arrowheadY = arrow.y + Math.sin(arrow.rotation) * 120;
// Check if arrowhead specifically hits bullseye (using actual bullseye asset size)
var dx = arrowheadX - target.x;
var dy = arrowheadY - target.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Use half the bullseye width as the hit radius (82.14 pixels)
var bullseyeRadius = 164.28 / 2;
var isBullseyeHit = distance <= bullseyeRadius;
// Only trigger if hitting bullseye
if (isBullseyeHit) {
// Arrow hit bullseye
arrow.isFlying = false;
arrow.velocityX = 0;
arrow.velocityY = 0;
targetHit = true;
LK.effects.flashObject(target, 0x00FF00, 500);
LK.getSound('hit').play();
// Show level complete popup
var levelPopup = new Text2('Level Complete!', {
size: 100,
fill: 0xFFD700
});
levelPopup.anchor.set(0.5, 0.5);
levelPopup.x = arrow.x;
levelPopup.y = arrow.y - 50;
game.addChild(levelPopup);
tween(levelPopup, {
y: levelPopup.y - 100,
alpha: 0
}, {
duration: 2000,
onFinish: function onFinish() {
levelPopup.destroy();
nextLevel();
}
});
arrows.splice(i, 1);
}
}
}
// Check win condition (completing level 25)
if (currentLevel > 25) {
LK.showYouWin();
}
// Check game over condition - if no arrows left and no arrow in flight
if (arrowsRemaining <= 0 && arrows.length === 0 && !currentArrow && currentLevel <= 25) {
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
}
// Check if arrows remaining is 0 but target is not hit, end the game
if (arrowsRemaining === 0 && !currentArrow && !targetHit) {
var anyArrowFlying = false;
for (var j = 0; j < arrows.length; j++) {
if (arrows[j].isFlying) {
anyArrowFlying = true;
break;
}
}
if (!anyArrowFlying) {
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
}
};
Wooden Bow. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Wood bow. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Arrow head. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat