Name | Author | Game Mode | Rating | |||||
---|---|---|---|---|---|---|---|---|
TrueColor and Resize | Violet CLM | Other | N/A |
#include "Resize v11.asc" //the Resize library includes the TrueColor library on its own, so we only need one #include line
#pragma require "TrueColorEx.png"
uint RainbowsFrameID;
ANIM::Set FrogAnimSet;
void onLevelLoad() {
Resize::Resize( //Triple the size of the Tuf Turtle enemy
jjAnimSets[ANIM::TUFTUR],
1, //Number of jjANIMATIONs used by the jjANIMSET
3, //How much to resize the sprites by--this argument is a float, so non-integer scales are also allowed
Resize::Method::Scale2x //What resizing algorithm to use--the Resize library offers several different algorithms, so check its documentation for the full list
);
Resize::Resize( //Do the same with the Lizard enemy
jjAnimations[jjAnimSets[ANIM::LIZARD].firstAnim + 4], //The ANIM::LIZARD set includes five different animations, mostly for Float Lizard enemies, but there aren't any Float Lizards in this level, so we only need the last animation
3, //Scale. The Resize library also allows shrinking sprites, of course, not just enlarging them.
Resize::Method::Scale2xSAI | Resize::Flags::OnlySpriteColors //A different method. Scale2x, used above, does not introduce any new colors into the resized sprite, but Scale2xSAI draws from elsewhere in the palette when necessary for blending nearby colors. The OnlySpriteColors flag is used here because we're going to be changing palettes a lot, and otherwise the blending would quickly look ugly.
);
TrueColor::ProcessPalette(); //A necessary first step whenever using the TrueColor library, this sets up the library's internal understanding of the palette and how to use it
TrueColor::EnableCaching(); //Like Resize::Flags::OnlySpriteColors, this is useful because we're going to be changing palettes. See the TrueColor library's documentation for a fuller explanation of what it does.
//Now we're going to create an animation of a frog using the TrueColor library, meaning that it'll be drawn using colors not appearing in the palette, whatever the palette. Creating a whole TrueColor animset can be accomplished in a single line, though here we use three lines in order to save a couple variables for later use. (The frog sprites are from Spelunky HD, uploaded to The Spriters Resource by SuperFlomm.)
TrueColor::Bitmap spriteSheet("TrueColorEx.png"); //Image containing four frames of a frog (and one additional frame used below)
FrogAnimSet = TrueColor::FindCustomAnim(); //FindCustomAnim does what it says and finds an ANIM::Set constant that has not yet been used by any other code in this level. We're storing the result in a global variable in order to refer back to it later when drawing these sprites.
Resize::AllocateAndResizeTrueColorSpriteSheet(
FrogAnimSet, //Which jjAnimSets entry to put these new animations in
spriteSheet, //Which bitmap image to grab the frames from
array<array<TrueColor::Coordinates>> = { //Now we have to specify where in the spriteSheet image (TrueColorEx.png) each sprite is, what its dimensions are, and (optionally) its hotSpot location.
{
TrueColor::Coordinates(0, 0, 54,56, -17,-36),
TrueColor::Coordinates(54, 0, 55,56, -17,-36),
TrueColor::Coordinates(109,0, 59,56, -17,-36),
TrueColor::Coordinates(168,0, 58,56, -17,-36)
} //note that the third argument to Resize::AllocateAndResizeTrueColorSpriteSheet is a nested array, so you could in principle define multiple animations within the animset, not just multiple frames within a single animation.
},
2.25, //A non-integer scale. Note that if the original images are already the right size, there's also a TrueColor::AllocateSpriteSheet function which has the same signature as Resize::AllocateAndResizeTrueColorSpriteSheet but without the scale and resizing method arguments, e.g. you could pass just the first three arguments above.
Resize::Method::BilinearInterpolation
);
//Now we're going to put together two more TrueColor images, but instead of using the fancy Resize::AllocateAndResizeTrueColorSpriteSheet shortcut function, we'll break it down into a few more steps for clarity.
RainbowsFrameID = jjAnimations[ //Once again we're creating an animset with only a single animation, though this time it has only two frames instead of four, and they'll be drawn concurrently/independently instead of subsequently.
jjAnimSets[
TrueColor::FindCustomAnim()
].allocate(
array<uint> = {
TrueColor::NumberOfFramesPerImage * 2 //Note the constant here--TrueColor images require multiple jjANIMFRAME objects, so it's important to multiply and/or divide TrueColor::NumberOfFramesPerImage whenever you get close enough to the jjAnimFrames array.
}
).firstAnim
].firstFrame;
TrueColor::Bitmap colorTable(128, 128); //We'll also create a TrueColor::Bitmap image from scratch, within the code of this level, instead of importing it from an external file. Other options include constructing a TrueColor::Bitmap from a jjSTREAM or a jjPIXELMAP.
for (uint x = 0; x < 128; ++x)
for (uint y = 0; y < 128; ++y) {
jjPALCOLOR color;
color.setHSL(y<<1, 255, x<<1);
colorTable.pixels[x][y] = color; //TrueColor::Bitmap::pixels is actually a nested array of TrueColor::AlphaColor objects, not of jjPALCOLORs, but we don't need the alpha channel for this particular image
}
colorTable.saveToAnimFrames( //Take this TrueColor::Bitmap and define a series of jjANIMFRAME objects from it
RainbowsFrameID, //Where in the jjAnimFrames array to save the image to
TrueColor::Coordinates(
0,0,128,128, //Save the entire TrueColor::Bitmap's image into the jjANIMFRAME objects, not just a cropped portion of it
-64,-64 //Put the hotspot in the center
)
);
spriteSheet.saveToAnimFrames(
RainbowsFrameID + TrueColor::NumberOfFramesPerImage, //Again note the constant here--while we were defining the jjANIMSET containing the frames starting at RainbowsFrameID, we asked for (TrueColor::NumberOfFramesPerImage * 2) frames in total, so the second image starts at (RainbowsFrameID + TrueColor::NumberOfFramesPerImage).
TrueColor::Coordinates(
0,56, //Origin
42,69, //Size
-21,0, //Hotspot
0,0,0,0, //Gunspot and Coldspot
true, //Draw this sprite at 50% opacity, instead of 100% opacity like all the other TrueColor images we've been working with
true //Format these jjANIMFRAMEs to be drawn as swinging vines, which have special transparency requirements
)
);
}
array<string> PaletteFilenames = {"Castle1.j2t", "Carrot1.j2t", "Labrat1.j2t", "Colon1.j2t", "Psych1.j2t", "Beach.j2t", "Diam1.j2t", "Tube.j2t", "Medivo.j2t", "Jungle1.j2t", "Inferno1.j2t", "Damn1.j2t"}; //A bunch of different tilesets to load palettes from
uint PaletteFilenameIndex = 0;
void onMain() {
//Finally, draw the TrueColor images we spent all that time creating and then saving into jjANIMFRAMEs. Although here they're just being drawn in onMain instead of being attached to any particular jjOBJ instances, that'd be fine too--collision detection would be handled perfectly, and there's even a TrueColor::DrawObject convenience function that more or less recreates jjOBJ::draw.
TrueColor::DrawRotatedSpriteFromCurFrame( //This function looks almost exactly like jjDrawRotatedSpriteFromCurFrame, though the sprite mode and sprite param arguments are not supported
320, 240,
RainbowsFrameID,
jjGameTicks << 1 //Angle
);
TrueColor::DrawSwingingVineSpriteFromCurFrame( //All the TrueColor drawing functions have variants with or without FromCurFrame, as well as variants to draw to jjCANVAS.
320, 0,
RainbowsFrameID + TrueColor::NumberOfFramesPerImage,
480, //Length
int(jjSin(jjGameTicks << 2) * 0x2000) //Curvature
);
TrueColor::DrawSprite(
480, 140,
FrogAnimSet,
0, //Remember, there's only one animation in FrogAnimSet, because the array starting at line 29 was of length 1.
(jjGameTicks >> 3) * TrueColor::NumberOfFramesPerImage,
(jjGameTicks & 32 == 0) ? 1 : -1 //Direction
);
if (jjGameTicks % 140 == 139) { //Every two seconds, change the palette to something else, to demonstrate that the TrueColor images are always drawn correctly, despite using colors not found in any of the different palettes.
jjPalette.load(PaletteFilenames[++PaletteFilenameIndex % PaletteFilenames.length]);
jjPalette.apply();
TrueColor::ProcessPalette(); //Be sure to call this again every time you call jjPAL::apply
}
}
Jazz2Online © 1999-INFINITY (Site Credits). We have a Privacy Policy. Jazz Jackrabbit, Jazz Jackrabbit 2, Jazz Jackrabbit Advance and all related trademarks and media are ™ and © Epic Games. Lori Jackrabbit is © Dean Dodrill. J2O development powered by Loops of Fury and Chemical Beats.
Eat your lima beans, Johnny.