A Pen by Gerard Ferrandez on CodePen.
Created
September 6, 2015 16:20
-
-
Save metropolian/517734567de736038d09 to your computer and use it in GitHub Desktop.
Yoshi's Island
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="screen"> | |
<span> | |
<img id="bkg0" src="map.gif" alt=""> | |
<img id="bkg1" src="map.gif" alt=""> | |
</span> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ------ Yoshis Island ------ | |
// Gerard Ferrandez - ge1doot - August 2005 (dhteumeuleu) | |
// GFX: from GBA Yoshi's Island TM (c)1995-2002 Nintendo | |
~ function() { | |
'use strict'; | |
var map = [ | |
// ---- map definition ---- | |
{ | |
src: "oam20.gif", | |
x: 0, | |
y: -256, | |
z: -30 | |
}, // big mountain | |
{ | |
src: "oam22.gif", | |
x: 0, | |
y: -172, | |
z: -30 | |
}, // house big mountain | |
{ | |
src: "oam24.gif", | |
x: 35, | |
y: -256, | |
z: -40 | |
}, { | |
src: "oam24.gif", | |
x: 35, | |
y: -256, | |
z: 0 | |
}, { | |
src: "oam24.gif", | |
x: -20, | |
y: -256, | |
z: -60 | |
}, // mountain | |
{ | |
src: "oam8.gif", | |
x: -40, | |
y: -256, | |
z: 0 | |
}, { | |
src: "oam8.gif", | |
x: 20, | |
y: -256, | |
z: -70 | |
}, // green talus | |
{ | |
src: "oam3.gif", | |
x: -40, | |
y: -256, | |
z: -25 | |
}, // red tower | |
{ | |
src: "oam51.gif", | |
x: -40, | |
y: -256, | |
z: -25, | |
gr: 1 | |
}, // ground | |
{ | |
src: "oam5.gif", | |
x: -25, | |
y: -256, | |
z: -95 | |
}, // volcano | |
{ | |
src: "oam32.gif", | |
x: 60, | |
y: -256, | |
z: -60 | |
}, { | |
src: "oam32.gif", | |
x: 50, | |
y: -256, | |
z: 40 | |
}, { | |
src: "oam32.gif", | |
x: -40, | |
y: -256, | |
z: 40 | |
}, // hill | |
{ | |
src: "oam19.gif", | |
x: 80, | |
y: -256, | |
z: -70 | |
}, { | |
src: "oam19.gif", | |
x: 80, | |
y: -256, | |
z: -40 | |
}, { | |
src: "oam19.gif", | |
x: 60, | |
y: -256, | |
z: 60 | |
}, { | |
src: "oam19.gif", | |
x: -60, | |
y: -256, | |
z: 50 | |
}, { | |
src: "oam19.gif", | |
x: -60, | |
y: -256, | |
z: 20 | |
}, // small hill | |
{ | |
src: "oam52.gif", | |
x: 80, | |
y: -256, | |
z: -70, | |
gr: 1 | |
}, { | |
src: "oam52.gif", | |
x: 60, | |
y: -256, | |
z: 60, | |
gr: 1 | |
}, { | |
src: "oam52.gif", | |
x: -60, | |
y: -256, | |
z: 50, | |
gr: 1 | |
}, // green ground | |
{ | |
src: "oam14.gif", | |
x: 50, | |
y: -256, | |
z: -20 | |
}, // grey donjon | |
{ | |
src: "oam51.gif", | |
x: 50, | |
y: -256, | |
z: -20, | |
gr: 1 | |
}, // ground | |
{ | |
src: "oam14.gif", | |
x: 0, | |
y: -256, | |
z: 10 | |
}, // grey donjon | |
{ | |
src: "oam50.gif", | |
x: 0, | |
y: -256, | |
z: 10, | |
gr: 1 | |
}, // castle water | |
{ | |
src: "oam11.gif", | |
x: -12, | |
y: -256, | |
z: 10 | |
}, { | |
src: "oam11.gif", | |
x: 12, | |
y: -256, | |
z: 10 | |
}, { | |
src: "oam11.gif", | |
x: 0, | |
y: -256, | |
z: -2 | |
}, { | |
src: "oam11.gif", | |
x: 0, | |
y: -256, | |
z: 22 | |
}, // grey towers | |
{ | |
src: "oam28.gif", | |
x: 60, | |
y: -256, | |
z: 15 | |
}, // towers with red roof | |
{ | |
src: "oam17.gif", | |
x: 50, | |
y: -256, | |
z: -80 | |
}, // dolmen | |
{ | |
src: "oam25.gif", | |
x: 65, | |
y: -256, | |
z: 30 | |
}, { | |
src: "oam25.gif", | |
x: 85, | |
y: -256, | |
z: 30 | |
}, { | |
src: "oam25.gif", | |
x: 70, | |
y: -256, | |
z: 10 | |
}, { | |
src: "oam25.gif", | |
x: 70, | |
y: -256, | |
z: -20 | |
}, // oranges | |
{ | |
src: "oam10.gif", | |
x: 0, | |
y: -200, | |
z: -70 | |
}, { | |
src: "oam10.gif", | |
x: 20, | |
y: -180, | |
z: -70 | |
}, { | |
src: "oam10.gif", | |
x: 40, | |
y: -170, | |
z: -50 | |
}, { | |
src: "oam10.gif", | |
x: 40, | |
y: -190, | |
z: -30 | |
}, // cloud | |
{ | |
src: "oam35.gif", | |
x: -50, | |
y: -160, | |
z: -10, | |
href: "http://codepen.io/ge1doot/" | |
}, // cloud castle | |
{ | |
src: "oam2.gif", | |
x: -65, | |
y: -256, | |
z: -50 | |
}, { | |
src: "oam2.gif", | |
x: -45, | |
y: -256, | |
z: -50 | |
}, { | |
src: "oam2.gif", | |
x: -40, | |
y: -256, | |
z: -70 | |
}, { | |
src: "oam2.gif", | |
x: -65, | |
y: -256, | |
z: -30 | |
}, { | |
src: "oam2.gif", | |
x: -80, | |
y: -256, | |
z: -80 | |
}, { | |
src: "oam2.gif", | |
x: -80, | |
y: -256, | |
z: -20 | |
}, { | |
src: "oam2.gif", | |
x: -90, | |
y: -256, | |
z: 0 | |
}, // fir | |
{ | |
src: "oam1.gif", | |
x: -60, | |
y: -256, | |
z: -40 | |
}, { | |
src: "oam1.gif", | |
x: -90, | |
y: -256, | |
z: -40 | |
}, { | |
src: "oam1.gif", | |
x: -100, | |
y: -256, | |
z: -20 | |
}, { | |
src: "oam1.gif", | |
x: -90, | |
y: -256, | |
z: -60 | |
}, { | |
src: "oam1.gif", | |
x: -40, | |
y: -256, | |
z: -80 | |
}, { | |
src: "oam1.gif", | |
x: -60, | |
y: -256, | |
z: -60 | |
}, { | |
src: "oam1.gif", | |
x: -60, | |
y: -256, | |
z: -90 | |
}, // small fir | |
{ | |
src: "oam23.gif", | |
x: 60, | |
y: -256, | |
z: -40 | |
}, { | |
src: "oam23.gif", | |
x: 60, | |
y: -256, | |
z: -30 | |
}, { | |
src: "oam23.gif", | |
x: 60, | |
y: -256, | |
z: -90 | |
}, { | |
src: "oam23.gif", | |
x: 70, | |
y: -256, | |
z: -90 | |
}, { | |
src: "oam23.gif", | |
x: 50, | |
y: -256, | |
z: -95 | |
}, { | |
src: "oam23.gif", | |
x: 90, | |
y: -256, | |
z: -40 | |
}, // flower | |
{ | |
src: "oam23.gif", | |
x: 95, | |
y: -256, | |
z: -50 | |
}, { | |
src: "oam23.gif", | |
x: 95, | |
y: -256, | |
z: -30 | |
}, { | |
src: "oam23.gif", | |
x: 80, | |
y: -256, | |
z: -20 | |
}, { | |
src: "oam23.gif", | |
x: 80, | |
y: -256, | |
z: -10 | |
}, { | |
src: "oam23.gif", | |
x: 100, | |
y: -256, | |
z: -10 | |
}, { | |
src: "oam23.gif", | |
x: 100, | |
y: -256, | |
z: 0 | |
}, // flower | |
{ | |
src: "oam6.gif", | |
x: 30, | |
y: -256, | |
z: 30 | |
}, { | |
src: "oam6.gif", | |
x: 20, | |
y: -256, | |
z: 40 | |
}, { | |
src: "oam6.gif", | |
x: 20, | |
y: -256, | |
z: 60 | |
}, { | |
src: "oam6.gif", | |
x: -20, | |
y: -256, | |
z: 30 | |
}, { | |
src: "oam6.gif", | |
x: -20, | |
y: -256, | |
z: 50 | |
}, { | |
src: "oam6.gif", | |
x: -30, | |
y: -256, | |
z: 60 | |
}, { | |
src: "oam6.gif", | |
x: -10, | |
y: -256, | |
z: 90 | |
}, // tree | |
{ | |
src: "oam9.gif", | |
x: 30, | |
y: -256, | |
z: 45 | |
}, { | |
src: "oam9.gif", | |
x: 35, | |
y: -256, | |
z: 60 | |
}, { | |
src: "oam9.gif", | |
x: 45, | |
y: -256, | |
z: 70 | |
}, { | |
src: "oam9.gif", | |
x: 50, | |
y: -256, | |
z: 90 | |
}, { | |
src: "oam9.gif", | |
x: -20, | |
y: -256, | |
z: 90 | |
}, { | |
src: "oam9.gif", | |
x: -15, | |
y: -256, | |
z: 70 | |
}, { | |
src: "oam9.gif", | |
x: -10, | |
y: -256, | |
z: 35 | |
}, // small tree | |
{ | |
src: "oam16.gif", | |
x: 0, | |
y: -256, | |
z: 30 | |
}, { | |
src: "oam16.gif", | |
x: 0, | |
y: -256, | |
z: 40 | |
}, { | |
src: "oam16.gif", | |
x: 0, | |
y: -256, | |
z: 50 | |
}, { | |
src: "oam16.gif", | |
x: 0, | |
y: -256, | |
z: 60 | |
}, { | |
src: "oam16.gif", | |
x: 0, | |
y: -256, | |
z: 70 | |
}, // plots | |
{ | |
src: "oam4.gif", | |
x: -25, | |
y: -200, | |
z: -95, | |
mz: 10 | |
}, { | |
src: "oam4.gif", | |
x: -25, | |
y: -220, | |
z: -95, | |
mz: 10 | |
}, { | |
src: "oam4.gif", | |
x: -25, | |
y: -210, | |
z: -95, | |
mz: 10 | |
}, // volcano smoke | |
{ | |
src: "oam33.gif", | |
x: -10, | |
y: -172, | |
z: -23 | |
}, { | |
src: "oam33.gif", | |
x: -15, | |
y: -169, | |
z: -21 | |
}, { | |
src: "oam33.gif", | |
x: -20, | |
y: -166, | |
z: -19 | |
}, { | |
src: "oam33.gif", | |
x: -25, | |
y: -163, | |
z: -17 | |
}, { | |
src: "oam33.gif", | |
x: -30, | |
y: -160, | |
z: -15 | |
}, // chain | |
{ | |
src: "oam38.gif", | |
x: 20, | |
y: -200, | |
z: 40, | |
mz: 2 | |
}, // seagull | |
{ | |
src: "oam18.gif", | |
x: 20, | |
y: -256, | |
z: 40 | |
} // Yoshi | |
]; | |
// ----- private vars ----- | |
var o = [], | |
ay = 2, | |
sin = Math.sin(ay * Math.PI / 180), | |
cos = Math.cos(ay * Math.PI / 180), | |
k = 0, | |
b1, b2; | |
// ----- prototype object ----- | |
var CObj = function(p) { | |
this.loaded = false; | |
this.x = p.x; | |
this.y = p.y; | |
this.z = p.z; | |
this.gr = p.gr || false; | |
// ---- insert image ----- | |
this.img = document.createElement("img"); | |
this.img.src = p.src; | |
if (p.href) { | |
// ---- menu link ----- | |
var a = document.createElement("a"); | |
a.href = p.href; | |
a.appendChild(this.img); | |
scr.elem.appendChild(a); | |
this.img.style.left = '0'; | |
this.css = a.style; | |
} else { | |
// ---- simple image ----- | |
scr.elem.appendChild(this.img); | |
this.css = this.img.style; | |
} | |
// ---- vertical animation ---- | |
this.mz = p.mz || false; | |
this.mzr = 0; | |
// ---- ground ---- | |
this.gr = p.gr || false; | |
}; | |
// ---- rotate function ----- | |
CObj.prototype.rotate = function() { | |
if (this.mz) { | |
this.mzr += 0.5; | |
this.y += 0.5; | |
if (this.mzr > this.mz) { | |
this.y -= this.mzr; | |
this.mzr = 0; | |
} | |
} | |
var x1 = this.x * cos - this.z * sin; | |
this.z = this.z * cos + this.x * sin; | |
this.x = x1; | |
var r = scr.width / (scr.width + this.z); | |
if (this.loaded) { | |
this.css.transform = this.css.webkitTransform = 'matrix(1,0,0,1,' + | |
(scr.width * 0.5 + (2 * this.x * r) - (this.w0 * r) * 0.5) + ',' + | |
(-scr.height - (2 * this.y * r) - (this.h0 * r)) + | |
')'; | |
this.css.zIndex = this.gr ? 0 : Math.round(100000 - this.z * 100); | |
} else { | |
// ----- image loaded ----- | |
if (this.img.complete) { | |
this.loaded = true; | |
this.w0 = this.img.width; | |
this.h0 = this.img.height; | |
if (this.gr) this.h0 /= 1.5; | |
this.css.left = '0'; | |
this.css.transform = this.css.webkitTransform = 'matrix(0,0,0,0,0,0)'; | |
} | |
} | |
}; | |
// ----- main loop ----- | |
var run = function() { | |
// ---- RAF ---- | |
requestAnimationFrame(run); | |
// ---- ay angle ---- | |
ay = (scr.width * 0.5 - pointer.x) / 100; | |
ay = Math.min(1.2, Math.max(-1.2, ay)); | |
sin = Math.sin(ay * Math.PI / 180); | |
cos = Math.cos(ay * Math.PI / 180); | |
// ---- background scrolling ---- | |
b1.left = Math.round(k) + "px"; | |
b2.left = Math.round(k + 512) + "px"; | |
k -= ay * 2; | |
if (k > 0) k -= 512; | |
else if (k < -512) k += 512; | |
// ---- rotate elements ---- | |
var i = 0, | |
p; | |
while (p = o[i++]) p.rotate(); | |
}; | |
// ---- screen ---- | |
var scr = { | |
elem: document.getElementById("screen"), | |
resize: function() { | |
var o = this.elem; | |
this.width = o.offsetWidth; | |
this.height = o.offsetHeight; | |
for (this.left = 0, this.top = 0; o != null; o = o.offsetParent) { | |
this.left += o.offsetLeft; | |
this.top += o.offsetTop; | |
} | |
} | |
}; | |
scr.resize(); | |
// ---- pointer ---- | |
var pointer = (function(canvas) { | |
var pointer = { | |
x: 0, | |
y: 0, | |
canvas: canvas, | |
isDown: false, | |
pointer: function(e) { | |
e.preventDefault(); | |
var touchMode = e.targetTouches; | |
var pointer = touchMode ? touchMode[0] : e; | |
this.x = pointer.clientX - this.canvas.left; | |
this.y = pointer.clientY - this.canvas.top; | |
}, | |
}; | |
[ | |
[window, 'mousemove,touchmove', function(e) { | |
this.pointer(e); | |
}], | |
[canvas.elem, 'mousedown,touchstart', function(e) { | |
this.pointer(e); | |
this.isDown = true; | |
}], | |
[window, 'mouseup,touchend,touchcancel', function(e) { | |
e.preventDefault(); | |
this.isDown = false; | |
}] | |
].forEach(function(e) { | |
for (var i = 0, events = e[1].split(','); i < events.length; i++) { | |
e[0].addEventListener(events[i], e[2].bind(pointer), false); | |
} | |
}.bind(pointer)); | |
return pointer; | |
}(scr)); | |
scr.elem.onselectstart = function() { | |
return false; | |
} | |
b1 = document.getElementById("bkg0").style; | |
b2 = document.getElementById("bkg1").style; | |
// ---- add some grass ---- | |
for (var i = 0; i < 40; i++) { | |
var r = Math.round(Math.random() * 180 - 90); | |
var a = Math.random() * 2 * Math.PI; | |
map.push({ | |
src: "oam27.gif", | |
x: Math.round(r * Math.cos(a)), | |
y: -256, | |
z: Math.round(r * Math.sin(a)) | |
}); | |
} | |
// ---- create objects ---- | |
for (var k = 0; k < map.length; k++) { | |
o.push( | |
new CObj( | |
map[k] | |
) | |
); | |
} | |
// ---- start engine ---- | |
pointer.Xi = 50; | |
run(); | |
}(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html { | |
overflow: hidden; | |
-ms-touch-action: none; | |
-ms-content-zooming: none; | |
} | |
body { | |
position: absolute; | |
background: #fff; | |
width: 100%; | |
height: 100%; | |
margin: 0; | |
padding: 0; | |
} | |
#screen { | |
position: absolute; | |
background: #000; | |
width: 512px; | |
height: 320px; | |
left: 50%; | |
top: 50%; | |
margin-left: -256px; | |
margin-top: -160px; | |
user-select: none; | |
outline: #eee solid 40px; | |
-webkit-transform: rotate(-3deg); | |
transform: rotate(-3deg); | |
} | |
#screen span { | |
position: absolute; | |
left: 0; | |
top: 0; | |
width: 100%; | |
height: 100%; | |
overflow: hidden; | |
} | |
#screen a, | |
img { | |
position: absolute; | |
border: none; | |
text-decoration: none; | |
left: -9999px; | |
} | |
*::selection { | |
background: transparent; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment