It seem like making a nice flight path and shaped danmaku is hard without much knowledge of Geometry and/or Trigonometry. ._.
I still haven't been able to make a flower shaped danmaku without manually placing bullet to draw them out....
Would anyone be so kind to give me a sample code of drawing a flower with math?
Please elaborate on which kind of flower you are looking for. Talos has used flowers before, and polar/parametric equations can easily generate a flower pattern.
Sorry for the late reply, the flower I want to make is like yuuka 2nd and 3rd spell card in PoFV, without the circle surrounding it, only the petal.
task CreateFlowerA1{
let angle = GetAngleToPlayer(objBoss);
let angle2 = GetAngleToPlayer(objBoss);
ascent(i in 0..24){
loop(6){
CreateShotA1(ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 1.5+i/12, angle, <graphic here>, 5);
CreateShotA1(ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 1.5+i/12, angle2, <graphic here>, 5);
angle+=360/6; angle2+=360/6;
}
angle+=7;
angle2-=7;
wait(3);
}
}
The 'erase' function for arrays is non-existant in ph3, though what is the alternative? The ph3/0.12m list points at 'length' though I am probably missing a vital thinking logic. Current documentation isn't providing insight on this.But the erase function still exists.
I have a set of laser obj ID inside an array upon creation. laserTrackID = laserTrackID ~ [obj]; Basically when the laser disappears, I want the corresponding obj ID to be deleted. However, dumping the entire array is not an option i.e: laserTrackID = [];
// useful function to 'yield' for given number of frames.
function wait(w) { loop(w) { yield; }
// loop four times using the variable i as the counter. This variable can be called within ascent
ascent(i in 0..4) {
CreateShotA1(bossX,bossY,3,90,i,0);
wait(60);
}
The above would fire a bullet every 60 frames (if we remove wait, it would fire them all at once) for total of four times. The bullet's graphic will be the ID of variable i, which changes every time the ascent loop walks through. Descent will count backwards.Could you post a screenshot of the bullets (and if possible a screenshot where you have a background, even if it's the default)? There are a few different things this could be.
In any case, the knife hitboxes will not be the same as they are in the Touhou games. The knife hitboxes in the official games can be wonky anyways, so that might be a good thing lol
I'll be direct: I'm trying to make a bullet spawn other bullets as it flies. Pretty simple. I have the code attached, but it only makes a single little bullet appear at when the large one is spawned. What did I do wrong? Here's the code: http://pastebin.com/E1v4TWjj
task EruptRing{
//Deleted code here
let obj = CreateShotA1(GetEnemyX(objBoss), GetEnemyY(objBoss), 3, angleT, 823, 10);
ObjShot_SetSpellResist(obj, true);
//More deleted code
let objangle = ObjMove_GetAngle(obj);
loop(8){
let obj2 = CreateShotOA1(obj, 15, objangle, 226, 5);
BulletCommands(obj2, dir);
objangle+=360/8;
}
//More deleted code
wait(20);
}
}
Oh, that looks a lot cleaner. Thanks for the help! Just one thing; what's the deal with the bulletcommands thing?
task BulletCommands(obj, dir){
if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}//Default kill to prevent (0,0) spawning
ObjMove_SetMaxSpeed(obj, 0);
ObjMove_SetAcceleration(obj, -5); //Will give 3 frames till 0, which is apx. 45 frames away from start location
wait(30);
ObjMove_SetAngularVelocity(obj, 5*dir);
ObjMove_SetSpeed(obj, 1);
wait(60); //Makes 300 degree turn
ObjMove_SetAngularVelocity(obj, 0);
ObjMove_SetMaxSpeed(obj, 2);
ObjMove_SetAcceleration(obj, 0.05);
}
Sure thing, here is a screenshot: http://oi58.tinypic.com/r70z9g.jpgOk so, this isn't unique to your bullets. If you didn't notice, the rest of the screen is also pixelated/aliased. The antialiasing in ph3 just isn't the greatest, and because you're in fullscreen 1440x1080 it looks really pixelated. If your sprites are small and meant for a 640x480 resolution (which is standard), then you're blowing them up to 2.25 times their usual size. You won't be able to fix this really, but if you play windowed at 640x480 you'll see that they look fine.
I'm sorry there is no background, I don't know yet how to even add the basic one.
Ok so, this isn't unique to your bullets. If you didn't notice, the rest of the screen is also pixelated/aliased. The antialiasing in ph3 just isn't the greatest, and because you're in fullscreen 1440x1080 it looks really pixelated. If your sprites are small and meant for a 640x480 resolution (which is standard), then you're blowing them up to 2.25 times their usual size. You won't be able to fix this really, but if you play windowed at 640x480 you'll see that they look fine.
Yes I noticed everything gets quite pixelated, definitley a shame but if it can't be helped I guess I'll stick with it, thank you Drake!
I now have another problem. A poster above shared this script for spawning bullets from another flying bullet. After seeing it I tought I'd try to use it to re-create the Sakuya's spellcard from the fighting games (http://img2.wikia.nocookie.net/__cb20100927055435/touhou/images/d/d6/UNL_Sakuyaspell1screenshot.png this one).
So, I managed to have the blue knives fly and leave behind them some grey knives, but I can't get these knives to move at all! I'm probably doing something extremely wrong, and my script will look horrendous to you guys, but after being stuck on this matter for 2 days I'm at a loss! ???
So here it is: http://pastebin.com/VZNpYYW7
The task I'm talking about is the "eruptingKnives" one.
task smoothStep(obj, x1, y1, t1){
let t0 = 0; // Start Time
while(t0 != t1) {
let x0 = ObjMove_GetX(obj);
let y0 = ObjMove_GetY(obj);
let dT = t0 ^ 2 * (3 - 2 * t0);
let smoothX = x0 + dT * (x1 - x0);
let smoothY = y0 + dT * (y1 - y0);
ObjMove_SetPosition(obj,smoothX,smoothY);
t0 ++;
yield;
}
}
I've avoided doing this in the past, but I'm redoing my system files and I want to make sure I get everything right...
- In a package script, how should I deal with CommonData for stuff that carries over between runs? (settings, Spell History, unlockables)
- How should I deal with stuff that doesn't carry over? (choosing a certain route unlocks a secret boss later in the run)
- How do I make stuff from 1) and 2) interact correctly with replays? (Watching a replay with a non-default number of lives works but doesn't change the user's setting, spell history doesn't change when you watch a replay of that spell, etc)
I know that's a lot of stuff to ask, but I don't want to put months into my script before discovering weird replay desynchs and other bugs. I'm aware that the wiki has the functions, but I'm confused about where they actually apply. Ideally, I'd want to have this stuff handled by the End Scene and Replay Scene scripts...
Is it possible to smoothStep the boss or bullets? How would I go about writing that code?Forgot about this, sorry. You mostly had it right, but you forgot or missed that smoothstep is supposed to bound the interpolated values between 0 and 1. When you increment t0 in your code, it's already 1. To get the smoothstepped value, -2(1)3+3(1)2 = 1, so your delta is 1, then you move to x0 + 1 * (x1 - x0) = x1 and oops you're done already. Notably, if you give smoothstep a value above 1, the squares and cubes will return a larger value than 1. With the input bounded from 0 to 1, you'll return a value between 0 and 1, as intended.
I did try to do this myself. I made a basic linear movement but that can be done easier using SetAtWeight/SetAtSpeed/SetAccel/etc. When I tried to make a smoothStep, it just jumps to the end destination (or Worse).
task smoothStep(obj, x1, y1, t1){
let t0 = 0; // Start Time
let x0 = ObjMove_GetX(obj); // X-origin
let y0 = ObjMove_GetY(obj); // Y-origin
while(t0 < 1) {
let dT = t0 ^ 2 * (3 - 2 * t0); // Time-delta
let smoothX = x0 + dT * (x1 - x0); // X-origin + X-delta
let smoothY = y0 + dT * (y1 - y0); // Y-origin + Y-delta
ObjMove_SetPosition(obj,smoothX,smoothY);
t0+=1/t1; // Ranges from 0 to 1 over t1 frames
yield;
}
}
I'm sorry if this is a stupid question, but I was wondering how to program collisions.You can apply if(GetObjectDistance(EffObj1,anyotherObj) < 32) { <deleteDesiredObj> } which will determine whether the obj is within 32 distance from each other.
Well, in specific, I'm trying to make it so that if one type of object collides with another type of object, the latter will be deleted.
Does anyone have any advice?
if( (ObjMove_GetX(obj1) - ObjMove_GetX(obj2))^2 + (ObjMove_GetY(obj1) - ObjMove_GetY(obj2))^2 <= (radius1 + radius2)^2 ) { <deleteDesiredObj> }
Those are arguments/variables that can be passed through when the task is called.The same can be achieved without declaring angle and just instantly parsing 'a' into the task. I think in this case your example is redundant.
task Bullet(x,y,s,a){
let angle = a;
CreateShotA1(x,y,s,angle........
}
The same can be achieved without declaring angle and just instantly parsing 'a' into the task. I think in this case your example is redundant.
If you're using bullets/lasers, this function cannot be used.Wut. GetObjectDistance() works with any objects.
Wut. GetObjectDistance() works with any objects.Why is the wiki confusing us then :ohdear:
Forgot about this, sorry. You mostly had it right, but you forgot or missed that smoothstep is supposed to bound the interpolated values between 0 and 1...Thanks for this, as this was the only part I was messing up because I didn't fully understand. Because I was too busy overthinking it (ex. "How Do I make sure it moves to X location at X amount of frames..."). This was kind of important for me so thank you again.
...All you need to do instead is have your t0 value go from 0 to 1, so if you want it to last t1 frames, you increase t0 by 1/t1 per frame.
Now, If I wanted to do a mirrored version of the smoothstep (from Origin to Target and back), I would have to divide Time(t1) by half, then have it smoothstep the first half and then the other half, so that it moves within the full time specified before I divided t1?I'm not entirely sure what you're looking to do here. This sounds like you would smooth start, smooth into the destination, smooth start back, and smooth back into the origin. If this is what you want, then yeah it would just be two smoothstep moves at half the time each.
Also, do I have to break the smoothstep if I call another movement?Mostly depends on whether the movement method either:
Also, how do I make sure any movement that I do (with the ObjMove functions) move to the location that I want at the time that I want?Well, ObjMove_SetDestAtTime() is pretty much exactly that. If you want more complicated movement to work within a number of frames you'd have to write it up yourself or precalculate how much time you need.
@Initialize
{
InitFrame();
TScore();
TGraze();
TPlayerLife();
TPlayerSpell();
TBossLife();
TBossTimer();
TCurrentFps();
TReplayFps();
InstallFont(dirCurrent~"ImpressBT.ttf"); //this is a line I added for the font
}
[...]
task TScore()
{
let objScore = ObjText_Create();
ObjText_SetFontType(objScore, "ImpressBT.ttf"); //this is another line I added to change the font
ObjText_SetText(objScore, "Score");
[...]
This sounds like you would smooth start, smooth into the destination, smooth start back, and smooth back into the origin. If this is what you want, then yeah it would just be two smoothstep moves at half the time each.Yep. That's what I want, so that's what I'll do.
Well, ObjMove_SetDestAtTime() is pretty much exactly that. If you want more complicated movement to work within a number of frames you'd have to write it up yourself or pre-calculate how much time you need.Well, it's like I want to combine ObjMove_SetDestAtFrame and ObjMove_SetDestAtWeight/Acceleration together, where the obj speeds up or slows down to the desired position, but within the time I choose.
How do I use custom fonts? I'm trying to change the font on the DefaultSystem, but all I get is Arial instead of the font I want.For ObjText_SetFontType you have to specify the name of the font, not its file name. Double click on the font file to display information about it, including its name.
How do I use custom fonts? I'm trying to change the font on the DefaultSystem, but all I get is Arial instead of the font I want.
For ObjText_SetFontType you have to specify the name of the font, not its file name. Double click on the font file to display information about it, including its name.
I threw together a section on fonts.
http://dmf.shrinemaiden.org/wiki/Sparen%27s_0.12m_to_ph3_Transition_Guide#Fonts (http://dmf.shrinemaiden.org/wiki/Sparen%27s_0.12m_to_ph3_Transition_Guide#Fonts)
I hope it is helpful.
while(!Obj_IsDeleted(obj)) {
if(ObjMove_GetX(obj) < 0||ObjMove_GetX(obj) > 386) {
loop(4) {
let bullet2 = ObjShot_Create(OBJ_SHOT);
// set up bullet2
ObjShot_AddShotA1(obj,bullet2,0);
}
}
if(ObjMove_GetY(obj) < 0) {
ObjMove_SetAngle(obj,-ObjMove_GetAngle(obj));
}
yield;
}
I've been trying to figure out how to make a decent background for scripts, but I have no idea what any of the effect/image/whatever functions do or how to use them. Is there any sort of guide for drawing BGs in ph3?Aye, it is completely gone the @BackGround. In ph3, create a regular 2D sprite and set the drawing priority type to the background value.
EDIT: I'm asking because the wiki's ph3 tutorial is missing the background functions section and it'd be really inefficient to learn 0.12m's functions and translate them.
let obj = ObjPrim_Create(OBJ_SPRITE_2D);
<etcetc for the scale,rect,etc>
Obj_SetRenderPriorityI(obj,20); // code to decide render priority which is basically a value between 0-100 afaik.
Obj_SetRenderPriorityI(obj,20); ( Background layer )
Obj_SetRenderPriorityI(obj,30); ( Player layer)
Obj_SetRenderPriorityI(obj,31); <--- will be drawn on top of the 30 value because 31 is > 30.
Obj_SetRenderPriorityI(obj,80); ( HUD layer )
task MagicCircleV3() {
/*placed on the main loop
Creates a Magic Circle that follows the boss around
DDC styled circle, rotates in XYZ slowly
*/
let angle = 0;
let circle = ObjPrim_Create(OBJ_SPRITE_3D);
ObjPrim_SetTexture(circle, imgEffect);
let enmx = ObjMove_GetX(objEnemy);
let enmy = ObjMove_GetY(objEnemy);
let x1 = -128;
let y1 = -126;
//ObjRender_SetAlpha(circle, 150);
while(!Obj_IsDeleted(objEnemy)) {
ObjSprite3D_SetSourceDestRect(circle, 127, 81, 255, 206);
ObjSprite3D_SetDestRect (circle, x1-128, y1-125, x1, y1);
ObjRender_SetX(circle, ObjMove_GetX(objEnemy));
ObjRender_SetY(circle, ObjMove_GetY(objEnemy));
//ObjRender_SetAngleX(circle, angle);
//ObjRender_SetAngleY(circle, angle);
//ObjRender_SetAngleZ(circle, angle);
angle++;
yield;
}
}
//ObjRender_SetAlpha(petal, 150);
ObjSprite2D_SetSourceRect(petal, 194, 230, 221, 249);
ObjSprite2D_SetDestCenter(petal);
ObjRender_SetAngleX(petal, angle);
ObjRender_SetAngleY(petal, angle);
ObjRender_SetAngleZ(petal, angle);
ObjMove_SetDestAtSpeed(petal, ObjMove_GetX(objEnemy), ObjMove_GetY(objEnemy), 5);
angle=angle+round(rand(0,5));
}
task ObjRender_SetDestAtSpeed(obj, x, y, s){
let ox = ObjRender_GetX(obj);
let oy = ObjRender_GetY(obj);
let dist = ((x-ox)^2 + (y-oy)^2)^0.5;
let dx = (x-ox)/dist*s;
let dy = (y-oy)/dist*s;
loop(floor(dist/s)){
ox += dx;
oy += dy;
ObjRender_SetX(obj, ox);
ObjRender_SetY(obj, oy);
yield;
}
ObjRender_SetX(obj, x);
ObjRender_SetY(obj, y);
}
task TEnd
{
while(ObjEnemy_GetInfo(objEnemy, INFO_LIFE) > 0)
{
yield;
}
let ex = ObjMove_GetX(objEnemy);
let ey = ObjMove_GetY(objEnemy);
TExplosionA(ex, ey, 10, 0.6);
DeleteShotAll(TYPE_ALL, TYPE_ITEM);//敵弾を全て削除
Obj_Delete(objEnemy);
loop(30){yield;}
CloseScript(GetOwnScriptID());
}
The problem with it is, during the 30 frames of waiting before the script is closed, any loops that are running will continue running... which is an issue for some cards I've been playing around with to relearn the ropes, because it means that bullets will continue spawning for 30 frames after the boss dies (at 0,0 as it happens, because after the boss object is deleted I guess it defaults a GetX/Y for a non-existant object to 0). I can fix that by removing the 30 frames of waiting and closing the script immediately, but then the cool little explosion animation won't play, because that requires the script to be open. In general, how can you script it so that bullets cease being fired when the boss dies, but there is still time for death animations to occur, without adding an "If (ObjEnemy_GetInfo(objEnemy, INFO_LIFE) > 0)" to every single CreateShot?...
@Initialize {
int;
main;
close;
ObjMove_SetDestAtFrame(objBoss, cx, cy, 30);
}
...
task int {
//Boss drawing stuff
}
task main {
loop{
loop(30){yield;}
CreateShotA1(ObjMove_GetX(objBoss),ObjMove_GetY(objBoss),3,90,1,10);
}
}
task close {
//What should I put here so that bullets cease being fired and an explosion animation plays in full when the boss is reduced to 0 life?
}
To answer your first question, no however you can use while(){} instead of loop{}.
task main {
while(Obj_IsDeleted(objBoss)!=true){
CreateShotA1(bx,by,3,45,1,10); wait(10);
CreateShotA1(bx,by,3,45,2,10); wait(10);
CreateShotA1(bx,by,3,45,3,10); wait(10);
CreateShotA1(bx,by,3,45,4,10); wait(10);
CreateShotA1(bx,by,3,45,5,10); wait(10);
}
}
Generally what I do is add if(ObjEnemyblahblhalblah){return;} to any yielding loops which is easier than adding that line everytime you create a bullet.
task main {
loop{
fire(1); wait(10);
fire(2); wait(10);
fire(3); wait(10);
fire(4); wait(10);
fire(5); wait(10);
}
}
function fire(graphic) {
if (Obj_IsDeleted(objBoss)==true){return;}
CreateShotA1(bx,by,3,45,graphic,10);
}
Like this?Code: [Select]task main {
loop{
fire(1); wait(10);
fire(2); wait(10);
fire(3); wait(10);
fire(4); wait(10);
fire(5); wait(10);
}
}
function fire(graphic) {
if (Obj_IsDeleted(objBoss)==true){return;}
CreateShotA1(bx,by,3,45,graphic,10);
}
Because that DID work, though I'm not sure it's what you meant.
ObjRender_SetScaleXYZ(obj,1.0,1.0,0);
ObjSprite2D_SetSourceRect(obj,0,1,256,128);
ObjSprite2D_SetDestCenter(obj);
Now comes the odd part. The floor logically doesn't covers the entire width of my field, so I simply increased the value to 512 for example, so the texture gets repeated, right? Wrong. I think more important is the misspelling of @MainLoop.... :colonveeplusalpha:
I think more important is the misspelling of @MainLoop.That wouldn't be a spelling... It's just a capitalization error...
That wouldn't be a spelling... It's just a capitalization error...:|
Mainloop vs MianLoop the former is not a spelling error, the latter, is. (Just thought so you can know the difference).
But you're talking to humans, not a computer. A spelling error to a human means missing word, extra word, or misplaced words. Not capitalization.
:|
It is a programming language. Any sort of syntactical error involving words could be called a spelling error; the interpreter doesn't care that it's lowercase, it's still an entirely different character. Why would you even need to point this out.
No, ph3 does not have that function. While you can make it yourself, I've found it easier to task enemies.No matter where I declare the hitbox functions, the enemy is untouchable and unshootable. Here's my script for reference: http://pastebin.com/DKjU9Hdd
task Fairy{
let obj = ObjEnemy_Create(OBJ_ENEMY);
ObjEnemy_Regist(obj);
ObjEnemy_SetLife(obj,100);
ObjPrim_SetTexture(obj,);
ObjSprite2D functions go here
separate task to handle the enemy's hitbox would be called here or you can handle the enemy's hitbox directly in the task.
}
task fairy {
let obj = Enemy(ry
hitboxHandle(obj);
}
task hitboxHandle(obj) {
while(!Obj_IsDeleted(obj)) {
// perform collision check
}
}
case(EV_GET_ITEM)
{
ObjSound_Play(item);
let itemType = GetEventArgument(0);
alternative(itemType)
case(1){
//Code that runs when collect the item
}
@Initialize{
let dir = GetCurrentScriptDirectory();
LoadItemData(dir~"item_data.dnh");
}
@Event{
alternative(GetEventType())
case(EV_GET_ITEM){
let itemType = GetEventArgument(0);
let objItem = GetEventArgument(1);
}
case(EV_USER+100000){
CreateItem(200, 200);
}
}
task CreateItem(x, y){
let obj = CreateItemU1(1, itemX, itemY, 0);
// maybe do other things?
}
Some different problem I bumped in and it felt really odd.
During the sprite adjusting of my floor I noticed something weird. My sprite is 256 wide and 128. So logically I set this code:Code: [Select]ObjRender_SetScaleXYZ(obj,1.0,1.0,0);
Now comes the odd part. The floor logically doesn't covers the entire width of my field, so I simply increased the value to 512 for example, so the texture gets repeated, right? Wrong.
ObjSprite2D_SetSourceRect(obj,0,1,256,128);
ObjSprite2D_SetDestCenter(obj);
The texture is actually stretched instead of repeated as in 0.12m. I started fiddling with various of functions and parameters such as using ObjSprite2D_SetDestRect as well but none of them had effect. This is quite weird as 3D sprites do repeat themselves if I set them (at least, as far as I can remember when I building my 3D stages. So what is the deal with 2D sprites?
Edit
This is embarrassing that I never had encountered this issue. Using SpriteList2D instead of regular Sprite2D will fix this problem. Thanks Drake for pointing it out.
Edit 2:
Apparently SpriteList2D does not listen to any of the SetAngle functions. Not the render, not the Move and also not the XYZ one. The hell is wrong right now.
Edit3:
Posted on bbs of dnh to see what Mkm has to say about it.
If all you want is the effect, you don't need items to pull that off. Basically what you need is two tasks. I personally handle this within the system script. Task 1 is what you will mainly call. Use task 1 to store all of the bullet ids on the screen using GetShotIdInCircleA2(x,y,radius,TARGET_ENEMY); save that to an array. Then ascent through the array calling task 2 which is where the break effect will play. You can use GetShotDataInfoA1(bullet id,TARGET_ENEMY,INFO_DELAY_COLOR); to set the color, this will return an array. Once you have all of the information you need from the bullet, make sure to delete it. Usually after setting the position of the effect is where I delete the bullet. You would use task 1 in @Event case(EV_END_BOSS_STEP){} will run everytime the boss has finished pattern so call it there.
You can also use events for manual bullet deletion by calling task 2 directly.
From what you're describing it seems like an incompatibility with player scripts. This is one of the reasons I created my own players, because I could not be bothered with such things as you're describing. I suggest building a player script that can support this. There is no way to really get around that. Not unless mkm added an EV_OBJ_DELETE that would call everytime an object is deleted. From there you could just run the same info as you normally would. I would advise you to make a request out to mkm to add such feature in the next version of ph3. To be honest who knows when it will come out, its been 3 months and alot of requests have been sent out to him. Probably has his plate full on that, I'm hoping he can find time to get it out soon for us.
Ultima: Why would you go through that when you could just call DeleteShotAll() or DeleteShotInCircle() using TYPE_ITEM?
let bulletwave = csd ~ "../SE/BulletWave.wav"; LoadSound(bulletwave);
"../" gets the previous directory, as opposed to the current one, which you want in this case (which is "./", or "GetCurrenScriptDirectory", in this case you'd want to use GetCurrentScriptDirectory~"path"). By the way, to use "../" properly, you'd want to do something like "./../", so that it gets the previous directory of the current directory.
ObjPrim_SetTexture(id[0],csd~"./stg6img/enm6a.png");
ObjPrim_SetTexture(id[1],csd~"./stg6img/enm6a.png");
ObjPrim_SetTexture(id[2],csd~"./stg6img/enm6b.png");
ObjPrim_SetTexture(id[3],csd~"./stg6img/enm6c.png");
ascent(i in 0..4){
ObjRender_SetPosition(id[i],CenX,CenY,0);
Obj_SetRenderPriorityI(id[i],22);
ObjRender_SetBlendType(id[i],BLEND_ALPHA);
ObjRender_SetScaleXYZ(id[i],1,1,0);
ObjSprite2D_SetSourceRect(id[i],0,0,384,448);
ObjSprite2D_SetDestCenter(id[i]);
}
ObjRender_SetScaleXYZ(id[3],1.1,1.1,0);
For one, you don't need to do the things involving id[0] id[1] id[2] id[3] inside the first loop; these would be executed four times for no reason.
You can also use ObjSprite2D_SetSourceRect() and ObjSprite2D_SetDestCenter() instead of manipulating individual vertices (2D sprite objects also automatically have 4 vertices) to make things cleaner and easier.
You can rewrite your first loop asCode: [Select]ObjPrim_SetTexture(id[0],csd~"./stg6img/enm6a.png");
ObjPrim_SetTexture(id[1],csd~"./stg6img/enm6a.png");
ObjPrim_SetTexture(id[2],csd~"./stg6img/enm6b.png");
ObjPrim_SetTexture(id[3],csd~"./stg6img/enm6c.png");
ascent(i in 0..4){
ObjRender_SetPosition(id[i],CenX,CenY,0);
Obj_SetRenderPriorityI(id[i],22);
ObjRender_SetBlendType(id[i],BLEND_ALPHA);
ObjRender_SetScaleXYZ(id[i],1,1,0);
ObjSprite2D_SetSourceRect(id[i],0,0,384,448);
ObjSprite2D_SetDestCenter(id[i]);
}
ObjRender_SetScaleXYZ(id[3],1.1,1.1,0);
And really just in general it seems to be a bit disorganized and you have repeating code in a few places. You should look into cleaning it up.
Anyways as for your main problem, I take note that
1) alpha1 and alpha2 are set to 0 and never change, so it's invisible.
2) emn6b is drawn on the same layer as enm6c, but is drawn before it, so regardless it would be drawn underneath everything.
task ay()
{
let bulletX = ObjMove_GetX(objEnemy);
let bulletY = ObjMove_GetY(objEnemy);
let density = 16;
let a = 0;
ascent(i in 0..density)
{
let bulletObj=CreateShotA1(bulletX, bulletY, 2,a,375, 10);
a += 360/density;
ObjMove_AddPatternA1(bulletObj,20,2,a-30-ang);
ObjMove_AddPatternA3(bulletObj,40,2,a+30-ang,NO_CHANGE,0,2,379);
ObjMove_AddPatternA1(bulletObj,60,2,a-30-ang);
ObjMove_AddPatternA3(bulletObj,80,2,a+30-ang,NO_CHANGE,0,2,376);
ObjMove_AddPatternA1(bulletObj,100,2,a-30-ang);
ObjMove_AddPatternA3(bulletObj,120,2,a+30-ang,NO_CHANGE,0,2,376);
ObjMove_AddPatternA1(bulletObj,140,2,a-30-ang);
ObjMove_AddPatternA3(bulletObj,160,2,a+30-ang,NO_CHANGE,0,2,378);
ObjMove_AddPatternA1(bulletObj,180,2,a-30-ang);
ObjMove_AddPatternA3(bulletObj,200,2,a+30-ang,NO_CHANGE,0,2,380);
while(!Obj_IsDeleted(bulletObj)){
if (ObjMove_GetX(bulletObj)<=GetStgFrameLeft+2 && ObjMove_GetX(bulletObj)>=GetStgFrameLeft-2){
CreateShotA1(ObjMove_GetX(bulletObj), ObjMove_GetY(bulletObj), 2,rand(-45,45),375, 10);
}
if (ObjMove_GetX(bulletObj)>=GetStgFrameWidth-2 && ObjMove_GetX(bulletObj)<=GetStgFrameWidth+2){
CreateShotA1(ObjMove_GetX(bulletObj), ObjMove_GetY(bulletObj), 2,rand(135,225),375, 10);
}
if (ObjMove_GetY(bulletObj)<=GetStgFrameTop+2 && ObjMove_GetY(bulletObj)>=GetStgFrameTop-2){
CreateShotA1(ObjMove_GetX(bulletObj), ObjMove_GetY(bulletObj), 2,rand(135,45),375, 10);
}
yield;
}
}
}
while (!Obj_IsDeleted(bossId))
{
SetSeed(4); // No such function :c
let angle = rand(0, 360);
CreateShotA1(ObjMove_GetX(bossId), ObjMove_GetY(bossId),
5, // Speed
angle,
DS_BALL_L_WHITE,
10); // Delay
WaitSeconds(0.1);
}
I want to make a spell have a random behavior, but be the same every time you play it.
For example:Code: [Select]while (!Obj_IsDeleted(bossId))
{
SetSeed(4); // No such function :c
let angle = rand(0, 360);
CreateShotA1(ObjMove_GetX(bossId), ObjMove_GetY(bossId),
5, // Speed
angle,
DS_BALL_L_WHITE,
10); // Delay
WaitSeconds(0.1);
}
You are wrong about the angle not being reset, and you didn't even refer to my problem :wat:Oh, I see. SetSeed is what you're referring to. Apologies, i had just got up,
(btw, this is an example I'd just made up, not an actual code from my game. So don't nitpick)
I'm currently writing a rather extensive beginner tutorial. Stay tuned, hopefully I'll be done within the week.
Any progress on that?
so... i'm not sure if i should ask this on this thread or what but i guess this belongs here:
regarding ph3 player scripting, is there some place that describes how to make a Player Script or someone who knows how to do so? for the thing i've seen there's nothing on these forums tutorials (regarding the player scripting matter of course), nor did my research on the threads come to a reliable result (or at least for the thing i could see)...
do tell me if this question is out of place please :V
oh well, i guess i'll just have to do the exact same thing :v thanks
@MainLoop {
LUNATIC_BLUE;
yield;
}
task LUNATIC_BLUE(){
let BGMobj = ObjSound_Create;
let BGMmp3 = GetCurrentScriptDirectory ~ "BGM.ogg";
ObjSound_Load(BGMobj,BGMmp3);
ObjSound_SetSoundDivision(BGMobj,SOUND_BGM);
ObjSound_SetVolumeRate(BGMobj,100);
ObjSound_SetLoopEnable(BGMobj,true);
ObjSound_SetLoopTime(BGMobj,0,284);
ObjSound_SetFade(BGMobj,60);
ObjSound_Play(BGMobj);
}
wait(60);//Assuming that compiling with finish in about a second.
Why are you doing this? This does not help you because the stage itself pauses until the thing is loaded.let shot = ObjShot_Create(OBJ_SHOT);
ObjShot_Regist(shot);
ObjMove_SetPosition(shot,getX(fam)+rand(-30,30),getY(fam)+rand(-30,30));
ObjMove_SetSpeed(shot,0);
ObjMove_SetAngle(shot,angle);
ObjShot_SetGraphic(shot,76);
ObjShot_SetDelay(shot,3);
Please just use let shot = CreateShotA2(getX(fam)+rand(-30,30),getY(fam)+rand(-30,30), 0, angle, 0, 0, 76, 3);
and then do your other edits.
#UserShotData
shot_image = "./Player_Shots.png"
ShotData{ id=1 rect=(1, 1,31,31) render=ADD alpha=64 collision=16 }
ShotData{ id=2 rect=(1,32,48,80) render=ADD alpha=64 collision=24 }
(And I load it in my player script's @Initialize via LoadPlayerShotData(current ~ "Player_ShotData.txt");)you didn't forget the ";" at the end of "LoadPlayerShotData(current ~ "Player_ShotData.txt"" right?It's in my post, the forum just made a smiley out of it. ( ;) <- ; ) ) Anyway, the problem only requires opening & saving the file, not modifying the player script any. So it has nothing to do with LoadPlayerShotData AFAIK.....
wait... isn't the "#UserShotData" misplaced? i never used it, nor knew of its existence, yet my tries on making player scripts worked fine without it :VFrom this post and the one before, I think you are getting confused. =) This problem is with "Default_Player_RumiaShotData.txt", not "Default_Player_Rumia.txt". The problem has nothing to do with player scripts as far as I can tell.
okay... what's all this UTF or ANSI stuff about? why not just saving them as plain normal txt files? i never heard of saving scripts like that..."Plain normal text" doesn't exist. A computer has to go from individual bits to readable text in one way or another.
also, the "#UsedShotData" i tried to mean was the one found inside the shotdata, right at the beginning... i fint it a bit... odd
task Glow {
loop(4){
Glowtrail();
wait(53);
}
}
task Glowtrail(){
let randir = rand(-0.5,0.5);
let obj = CreateShotB2(BossX,BossY-45,randir,-3,0,0.05,0,2,308,15);
while(!Obj_IsDeleted(obj)){
//stuff
}
}
or you could use ObjShot_SetDeleteFrame() to specify when to delete the child bullets instead. Only thing is that you won't get the fade out, if that matters.You also could decrease the alpha of the bullet by what you want per frame with ObjRender_SetAlpha (and delete the object when alpha <= 0) and use ObjShot_SetIntersectionCircleA1 with 0 as radius to make fadeout bullet without hitbox.
"wait(10)" is the correct amount of time I need for the bullets to appear, but it's too quick for them to disappear. I'm thinking I need to move "ObjShot_FadeDelete(MiniLgt);" somewhere else? Like in a loop inside the while loop, or maybe a different task entirely?
...Actually thinking about it, putting it in a different task sounds like it could work... I might mess around with that in the meantime and see if I can come up with something.
You also could decrease the alpha of the bullet by what you want per frame with ObjRender_SetAlpha (and delete the object when alpha <= 0) and use ObjShot_SetIntersectionCircleA1 with 0 as radius to make fadeout bullet without hitbox.
It's not the easiest way but it work. I think.
task ManualFadeDelete(obj,time) // time is a time before it's completely deleted.
{
let alpha = 255;
let ratio = 255/time;
ObjShot_SetIntersectionEnable(obj,false); // remove the hitbox from a bullet.
while(alpha>0)
{
alpha -= ratio;
ObjRender_SetAlpha(obj,alpha); // the alpha of a bullet need to be updated every frame.
yield;
}
Obj_Delete(obj);
}
task deletetrail(obj2) {
wait(45);
ObjShot_FadeDelete(obj2);
}
Oh, I just wanted to add that that I looked under functions, and I found no way to get the hp of the enemy so I could delete the object.
while(ObjEnemy_GetInfo(objBoss,INFO_LIFE)>0){yield;}
The one enemy that spawns does not dieYou never tell the enemy to be deleted. Usually, people will have a while(ObjEnemy_GetInfo(objEnemy,INFO_LIFE)>0) rather than a simple loop and have Obj_Delete(objEnemy); after it. That way it will run the attack routines and/or collision detection while it has life and delete itself when it runs out.
Boss does not show upYou have to load every script before you can start it. You would want something like this:
let Script = LoadScript(dir ~ "Stage 1 Boss.txt");
StartScript(Script);
Alternatively you could just have the boss be created by the stage script itself instead of allowing another one to handle it but that's up to you.Script just ends randomly (assuming because the boss script is never opened)That is correct, the boss script is never started because it was never loaded.
Code: [Select]let Script = LoadScript(dir ~ "Stage 1 Boss.txt");
StartScript(Script);
It's certainly a stupid question but what is the exact meaning of the "../" used on pathing? It's seems to be a sort of "back to the previous folder" but... I'm not sure.
And also the "~" is used to concatenate string. But is there an operator or a function to do the opposite? For example if I have a string like "text1text2" and I want to remove "text2" and keep only "text1" how I can do? It's possible?
And also the "~" is used to concatenate string. But is there an operator or a function to do the opposite? For example if I have a string like "text1text2" and I want to remove "text2" and keep only "text1" how I can do? It's possible?Actually there sort of is a way. Look up the function SplitString on the wiki.
function RedRocket {
let RedMsl = ObjShot_Create(OBJ_SHOT);
ObjShot_Regist(RedMsl);
ObjPrim_SetTexture(RedMsl,RedMissleBullet);
ObjSprite2D_SetSourceRect(RedMsl,0,0,32,40);
while(!Obj_IsDeleted(RedMsl)){
ObjShot_SetIntersectionLine(RedMsl,16,4,16,36,4);
yield;
}
}
So I attempted to create a custom bullet for a script using ObjShot_Create and other commands that I figured went with it. I had a picture ready, and I set the code up similar to how I rendered the boss (via Helipolis's tutorial). But it didn't work when I tried to shoot it from the boss.Code: [Select]function RedRocket {
let RedMsl = ObjShot_Create(OBJ_SHOT);
ObjShot_Regist(RedMsl);
ObjPrim_SetTexture(RedMsl,RedMissleBullet);
ObjSprite2D_SetSourceRect(RedMsl,0,0,32,40);
while(!Obj_IsDeleted(RedMsl)){
ObjShot_SetIntersectionLine(RedMsl,16,4,16,36,4);
yield;
}
}
Other than probably not getting the coding right, I placed "RedRocket" as the bullet to shoot... But now thinking about it, putting a function or task inside the bullet ID seems a bit silly.
So how would I actually go about creating a custom bullet? I'm under the impression though that I'd need to paste the code for the custom bullet in every script I want it in, which may be unadvised.
From this happening though, I started making my own shot sheet, which I think I understand how to do, but I'd like some advice, like on mistakes to avoid and such. I can ask for that in this thread, right? For some reason, I feel like this might not be the right place to ask for advice on that.
Thanks for the help!
ascent (i in 0..25) {
count+=360/8;
CreateShotA2(BossX-90+i*8,BossY-90+i*8,1.3,count+variance,0.01,2.7,202,20);
CreateShotA2(BossX-90+i*8,BossY-90+i*8,1,count+variance,0.01,2.5,202,20);
CreateShotA2(BossX-90+i*8,BossY-90+i*8,0.7,count+variance,0.01,2.3,RedRocket,20);
wait(1);
}
You'll probably face palm when you see it. :V
Unable to be interpreted (Don't forget ";"s).
(解釈できないものがあります(「;」を忘れていませんか))
F:/Touhou project/th_dcs_ph3/script/thdcs/test.txt
test.txt line(行)=15
It's seems there is not problem with this when I comment the ObjEnemy_SetIntersectionCircleToPlayer.
So, I'm attempting to create my own dialogue script ( http://pastebin.com/8WTfSqJ6 )Use render priorities. http://dmf.shrinemaiden.org/wiki/Object_Functions#Obj_SetRenderPriority (http://dmf.shrinemaiden.org/wiki/Object_Functions#Obj_SetRenderPriority)
Use render priorities. http://dmf.shrinemaiden.org/wiki/Object_Functions#Obj_SetRenderPriority (http://dmf.shrinemaiden.org/wiki/Object_Functions#Obj_SetRenderPriority)Is there a function for the border for text, or is that a custom font thing?
Changing Z changes the position of the object, not on which layer it is rendered.
EDIT: Also, I suggest using a border for that text or making the colors brighter - it's not particularly easy to read the bluer part on the blue background.
// initialize stuff
@Initialize {
loadGraphics;
renderStage;
renderCamera;
}
// Function for loading all graphics into separate thread.
function loadGraphics {
// Stage 1
LoadTextureInLoadThread(balbg);
LoadTextureInLoadThread(balvloer);
LoadTextureInLoadThread(balmuur);
LoadTextureInLoadThread(balmat);
LoadTextureInLoadThread(balplafon);
LoadTextureInLoadThread(balplafon2);
LoadTextureInLoadThread(balslinger);
LoadTextureInLoadThread(balvspot);
LoadTextureInLoadThread(ballampion);
}
task renderStage {
Reset2DCamera; // Reset any possible 2D camera settings.
scrollStage; // Grand stage scrolling handler.
// Enable fog for the game. Fog minimum, maximum and colours are handled in threads.
SetFogEnable(true);
//------------------------------------------------------------------------------------------------------------------------------------------
// Stage 1 render
SetCameraPerspectiveClip(10,4096);
etc.................
Have a look at the text functions (http://dmf.shrinemaiden.org/wiki/Text_Object_Functions) on the wiki., there are several border functions.Aaaand I'm an idiot who can't find anything. Thank you so much!
Did anybody ever encountered textures/sprites being loaded but not properly visible in game? See below.
[attach=1]
This often happens when you simply boot the stage script for the first time (Note: this is not a package script, just plain stage for now). If I reload it with backspace then everything is fine. Sometimes the lanterns (red cubicles) won't proper show and sometimes the entire stage (as seen here). I want to avoid people playing this the ugly way when they "boot" my game.
Obj_SetRenderPriority(objPlayer, 0.95);
I am creating a player script and want to set different shots for unfocused and focused movement. Is there a way to check whether the player is focused or is there something else for player scripts?
I suggest that you look at a player script for yourself and see how it is done.I found out, but thanks anyway.
Hint: Virtual Keys
./../resource/playershots.png
. That was so obvious.task TShot {
loop {
let x = GetPlayerX;
let y = GetPlayerY - 4;
let shot = GetVirtualKeyState(VK_SHOT);
let focus = GetVirtualKeyState(VK_SLOWMOVE);
if (shot == KEY_PUSH || shot == KEY_HOLD) {
if (focus == KEY_PUSH || focus == KEY_HOLD) {
CreatePlayerShotA1(x - 2, y, 10, 270, 2, 1, SPIKED_SEED);
CreatePlayerShotA1(x + 2, y, 10, 270, 2, 1, SPIKED_SEED);
CreatePlayerShotA1(x - 2, y, 10, 235, 1, 1, SPIKED_SEED);
CreatePlayerShotA1(x + 2, y, 10, 315, 1, 1, SPIKED_SEED);
CreatePlayerShotA1(x - 2, y + 8, 10, 90, 1, 1, SPIKED_SEED);
CreatePlayerShotA1(x + 2, y + 8, 10, 90, 1, 1, SPIKED_SEED);
}
else {
CreatePlayerShotA1(x, y, 10, 270, 5, 1, SILVER_ARROW);
}
}
yield;
}
}
This may sound kind of dumb, but is there a way to save screenshots in the ph3 version? In the wiki i search for "screenshot" but there's only pressing "Home" for the 0.12m version. Googling* also didn't help much.
*I'm the paranoid who uses duckduckgo instead of google.
task fireAfroCrawlShot00(obj) {
let sf = 0;
let dir = 0;
let crawlShot00 = CreateShotA(ObjMove_GetX(obj),ObjMove_GetY(obj),10);
let crawlShot01 = CreateShotA(ObjMove_GetX(obj),ObjMove_GetY(obj),10);
dir = GetAngleToPlayer(obj);
SetShotDataA(crawlShot00,0,3,dir,0,0,3,87);
SetShotDataA(crawlShot01,0,3,dir,0,0,3,87);
while(!Obj_IsDeleted(obj)) {
ObjMove_SetAngle(crawlShot00,dir);
ObjMove_SetAngle(crawlShot01,-dir);
dir = 12*sin(sf);
sf+=8;
yield;
}
}
Second one: How do I produce shapes using the correct math? Like a square, triangle, star. I've been staring at graphs and other gifs on the internet but I simply don't get how to transform the correct code. If someone can show me a simple example I can perhaps try to understand what is going on.I assume you are not referring to ShootShape.
task SpawnStarA1(n){
if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}//Default kill to prevent (0,0) spawning
let randx = rand(-75,75);
let randy = rand(-75,75);
let angleT = 0;//0 needed for nice star
loop(90){
let modulus = 12/cos((2/n)*acos(cos(n*angleT/2)));//where n is number of sides. Flip across y = x to get pentagram
CreateBullet(randx+modulus*sin(angleT),randy+modulus*cos(angleT), 0);
angleT+=9;//Cycle 810 degrees.
}
}
The let modulus
is the radius portion of the polar coordinate of each given spawn point, while angleT is the angle portion.
I assume you are not referring to ShootShape.ShootShape?
There are ways to use polar and parametric equations in Danmakufu, and then you can use a rotation matrix to alter the angle of given shape. You can also define a 2D array with the shape you would like or read from a binary text file, and then apply the rotation matrix there as well.I'll be honest to say that none of this actually makes sense to me. It feels like magic, honestly. Even if I am allowed to use your code as example, just blatantly copy/pasting it and adjusting here and there still won't make me understand it though.
Is this what you mean? Or are you referring to a generic screenshot, which puu.sh and a number of other things support?
First one is a "crawling" or continuous curving shot, like the ones from SA I think.In your code, you are replacing dir (which is GetAngleToPlayer) with 12*sin(sf),, causing it to oscillate around the angle 0. Adding another variable, like let shift = 0, then putting shift = 12*sin(sf) in the loop, and putting dir+shift and dir-shift as the angles should do the trick.
Second one: How do I produce shapes using the correct math? Like a square, triangle, star. I've been staring at graphs and other gifs on the internet but I simply don't get how to transform the correct code. If someone can show me a simple example I can perhaps try to understand what is going on.
let sides = 8; //number of edges
let bullets = 24; //number of bullets in each edge
let size = 48; //how large each edge is
let x = EnemyX;
let y = EnemyY;
ascent(i in 0..sides){
let sangle = 360/sides*i; // angle of the edge
let xinc = (size/bullets)*cos(sangle);
let yinc = (size/bullets)*sin(sangle);
ascent(b in 0..bullets){
CreateShotA1(x, y, 0, sangle, 30, 10);
x+=xinc;
y+=yinc;
}
}
task renderScore(x, y, amt, color) {
let pathDigit = GetCurrentScriptDirectory ~ "../resource/digits_small.png";
let obj = ObjPrim_Create(OBJ_SPRITE_LIST_2D);
ObjPrim_SetTexture(obj, pathDigit);
ObjRender_SetBlendType(obj, BLEND_ALPHA);
ObjRender_SetAlpha(obj, 127);
ObjRender_SetColor(obj, color[0], color[1], color[2]);
let listNum = DigitToArrayBaseWC(amt, 16);
let digits = length(listNum);
ascent (j in 0 .. 30) {
ObjRender_SetY(obj, y - 8 - j);
ObjSpriteList2D_ClearVertexCount(obj);
ascent (iObj in 0 .. digits) {
let num = listNum[iObj];
ObjRender_SetX(obj, x + 2 * digits - 4 * iObj);
ObjSpriteList2D_SetSourceRect(obj, num * 16, 0, (num + 1) * 16, 16);
ObjSpriteList2D_SetDestRect(obj, 0, 0, 8, 8);
ObjSpriteList2D_AddVertex(obj);
}
// This one.
yield;
}
ObjSpriteList2D_ClearVertexCount(obj);
ObjRender_SetY(obj, y - 22);
Obj_Delete(obj);
}
Are you sure it's the yield? If that were the case, then all you would notice is that the object doesn't show up, which doesn't indicate a whole lot. What tests have you done? Have you tried commenting out the inner loop and doing something else more noticeable to confirm it is the yield?I put an error message right after the loop, and it didn't show; in other words, the loop doesn't break. In case you're curious, here's the whole file (it's an item script):
#include "../item/itemConsts.dnh"
#include "../prologue.dnh"
@Initialize {
LoadItemData(GetCurrentScriptDirectory ~ "../item/items.dnh");
SetDefaultBonusItemEnable(false);
}
task getItem(type, objItem) {
let x = ObjMove_GetX(objItem);
let y = ObjMove_GetY(objItem);
alternative (type)
case (POINT_ITEM) {
let piv = getPIV;
let y = GetPlayerY;
let multiplier = min(1.0, 1.25 - y / 600);
addScore(multiplier * piv);
addElemPoints(FIRE, multiplier * multiplier * 16);
renderScore(x, y, roundScore(multiplier * piv), [[255, 255, 255], [255, 255, 64]][multiplier == 1]);
}
case (GREEN_ITEM) {
addPIV(32);
renderScore(x, y, 32, [64, 192, 64]);
}
case (LIFE_FRAGMENT) {
setLifeFrag(getLifeFrag + 1);
if (getLifeFrag >= getLifeFragR) {
setLifeFrag(getLifeFrag - getLifeFragR);
SetPlayerLife(GetPlayerLife + 1);
setLifeFragR(getLifeFragRR + 1);
}
renderScore(x, y, 1, [255, 64, 255]);
}
case (BOMB_FRAGMENT) {
setBombFrag(getBombFrag + 1);
if (getBombFrag >= getBombFragR) {
setBombFrag(getBombFrag - getBombFragR);
SetPlayerSpell(GetPlayerSpell + 1);
}
renderScore(x, y, 1, [202, 255, 192]);
}
}
task renderScore(x, y, amt, color) {
let pathDigit = GetCurrentScriptDirectory ~ "../resource/digits_small.png";
let obj = ObjPrim_Create(OBJ_SPRITE_LIST_2D);
ObjPrim_SetTexture(obj, pathDigit);
ObjRender_SetBlendType(obj, BLEND_ALPHA);
ObjRender_SetAlpha(obj, 127);
ObjRender_SetColor(obj, color[0], color[1], color[2]);
let listNum = DigitToArrayBaseWC(amt, 16);
let digits = length(listNum);
ascent (j in 0 .. 30) {
ObjRender_SetY(obj, y - 8 - j);
ObjSpriteList2D_ClearVertexCount(obj);
ascent (iObj in 0 .. digits) {
let num = listNum[iObj];
ObjRender_SetX(obj, x + 2 * digits - 4 * iObj);
ObjSpriteList2D_SetSourceRect(obj, num * 16, 0, (num + 1) * 16, 16);
ObjSpriteList2D_SetDestRect(obj, 0, 0, 8, 8);
ObjSpriteList2D_AddVertex(obj);
}
yield;
}
ObjSpriteList2D_ClearVertexCount(obj);
ObjRender_SetY(obj, y - 22);
Obj_Delete(obj);
}
@Event {
alternative (GetEventType)
case (EV_DELETE_SHOT_TO_ITEM) {
let shot = GetEventArgument(0);
let position = GetEventArgument(1);
if (length(position) > 0) {
createItemU1(GREEN_ITEM, position[0], position[1], 0);
}
CollectAllItems;
}
case (EV_GET_ITEM) {
getItem(GetEventArgument(0), GetEventArgument(1));
}
}
In your code, you are replacing dir (which is GetAngleToPlayer) with 12*sin(sf),, causing it to oscillate around the angle 0. Adding another variable, like let shift = 0, then putting shift = 12*sin(sf) in the loop, and putting dir+shift and dir-shift as the angles should do the trick.Gaaaah it was that easy I see. Now I understand my error as well. Working like a charm now, thank you for the help all.
Gaaaah it was that easy I see. Now I understand my error as well. Working like a charm now, thank you for the help all.
The whole shape thing is a pain in the butt huh. I did manage to take a look at the example of Sparen. It draws a nice pentagram but seems the bullets are more spaced out towards the points of the star. I'm not trying to create anything extremely complicated. A simple square / triangle for example and maybe star at max. I'll study Sparen and your examples and get cracking on the shapes and such tonight after dinner and after some work on Stage 2 of my game (it is near completion). Will inform about the success of the shapes.
The problem isn't that the yield isn't working, but that the loop doesn't end. That's a big difference; if the yield wasn't working, you'd expect the loop to end, just instantly.
Keeping that difference in mind, the yield works fine, but the problem is that it yields to nothing. An item script is basically the same as any other, structurally. You probably know you need a yield in the @MainLoop for boss scripts, and this (along with plural, stage, and player scripts) is no different.
To explain: where does this yield statement lead to? Nowhere, right? The script hits the yield statement, it goes "ok I'll stop here and resume later". Maybe some other events are triggered, maybe some other functions or tasks are run. If any of them yield, "ok I'll stop here and resume later". But right now, there's nothing that ever resumes the threads. If you stick a yield in @MainLoop, which runs every frame, then @MainLoop will yield over to whatever is next in the thread queue and everything will work as intended.
A reminder that a new version of Danmakufu has been released.
By the way, is it possible to change the background at runtime?
What do you mean? By using CommonData, you can change the background at will.
Could you please elaborate or show an example?
Have a CommonData in your stage that changes once a certain thing has happened. Have a counter in your Background file, and have an if statement in the main loop of your background that, if the CommonData has been triggered and the counter is within a certain value, something changes and the counter is incremented.
I would show an example but my DEC Stage 6 background code is probably overkill for an example.
One question: why would I need a counter?
For smooth transitioning from one background to another. If you just set completely different stuff within one frame, it is extremely disorienting
// background
#include "./../prologue.dnh"
let bSpell = false;
let current = GetCurrentScriptDirectory();
let w = GetStgFrameWidth;
let h = GetStgFrameHeight;
let obj;
@Initialize {
let path = current ~ backgroundImage[getBGIndex];
obj = ObjPrim_Create(OBJ_SPRITE_2D);
ObjPrim_SetTexture(obj, path);
ObjRender_SetBlendType(obj, BLEND_ALPHA);
ObjSprite2D_SetSourceRect(obj, 0, 0, w, h);
ObjSprite2D_SetDestRect(obj, 0, 0, w, h);
Obj_SetRenderPriority(obj, 0.21);
changeBackground;
}
@MainLoop {
let objScene = GetEnemyBossSceneObjectID();
bSpell = objScene != ID_INVALID && ObjEnemyBossScene_GetInfo(objScene, INFO_IS_SPELL);
yield;
}
task changeBackground {
let prev = getBGIndex;
loop {
if (getBGIndex != prev) {
let path = current ~ backgroundImage[getBGIndex];
let newObj = ObjPrim_Create(OBJ_SPRITE_2D);
ObjPrim_SetTexture(newObj, path);
ObjRender_SetBlendType(newObj, BLEND_ALPHA);
ObjSprite2D_SetSourceRect(newObj, 0, 0, w, h);
ObjSprite2D_SetDestRect(newObj, 0, 0, w, h);
Obj_SetRenderPriority(newObj, 0.21);
ascent (i in 0 .. 120) {
ObjRender_SetAlpha(obj, 255 - (i / 120 * 255));
ObjRender_SetAlpha(newObj, i / 120 * 255);
yield;
}
obj = newObj;
}
prev = getBGIndex;
yield;
}
}
@Finalize {
Obj_Delete(obj);
}
I happened to do this without a counter:
I think I beat you this time.
It seems like that's something enforced by Danmakufu. If you were testing your own scripts, you could design a quick package script to run the singles/plurals/stages you are making, since the "retry script" hotkey is disabled in packages. It's a bit tedious, though, and I'm not sure whether it's worth the time and effort.
Unfortunately, backspace is not bound to a virtual key, so you can't force the key to a certain press state.
... This leads me to believe that Danmakufu has a "default package" that runs singles and plurals, which you can't edit. It seems that the resource folder only contains the stage codes for running plurals and singles, which are used by this hypothetical "hidden default package".
Of course, this is just my speculation, and may not actually be the case. However, what I can do is suggest to mkm a function that can change the key for retrying scripts, just like I had requested SetSkipModeKey.
Are you, perhaps, making a kind of typing game in Danmakufu?
Semi related, speaking of CommonDataAreas, why is it that when I try get the data it returns me the default value instead?
For example SetAreaCommonData("BGM","Vol",100). If I want to GetAreaCommonData("BGM","Vol",0) it will always keep returning me the 0 instead of the 100 as stored. Am I missing something?
It seems like that's something enforced by Danmakufu. If you were testing your own scripts, you could design a quick package script to run the singles/plurals/stages you are making, since the "retry script" hotkey is disabled in packages. It's a bit tedious, though, and I'm not sure whether it's worth the time and effort.
Unfortunately, backspace is not bound to a virtual key, so you can't force the key to a certain press state.
... This leads me to believe that Danmakufu has a "default package" that runs singles and plurals, which you can't edit. It seems that the resource folder only contains the stage codes for running plurals and singles, which are used by this hypothetical "hidden default package".
Of course, this is just my speculation, and may not actually be the case. However, what I can do is suggest to mkm a function that can change the key for retrying scripts, just like I had requested SetSkipModeKey.
Are you, perhaps, making a kind of typing game in Danmakufu?
They're in the resource/script/ directory. Nothing about backspace, though.
It seems that the resource folder only contains the stage codes for running plurals and singles, which are used by this hypothetical "hidden default package".
I meant more like the Engine throwing errors because there is no such commondata defined but it seems like SetAreaCommonData already behaves like setting it but it is non existent or so ???
Oh well.
Why does StartStageScene throw an error about not finding the player? I've called SetStageIndex, SetStageMainScript, and SetStagePlayerScript, and don't know what I missed.
Semi related, speaking of CommonDataAreas, why is it that when I try get the data it returns me the default value instead?U dont forget this?
For example SetAreaCommonData("BGM","Vol",100). If I want to GetAreaCommonData("BGM","Vol",0) it will always keep returning me the 0 instead of the 100 as stored. Am I missing something?
Do the text file object functions fail to handle UTF-16LE correctly? Of course, you can try encoding your file in ShiftJIS, until you want to translate your game into something such as Korean.
Unicode little endian...? I'm sure it should work properly. All of my codes are encoded with UTF-8 without the Byte order mark, though.
I wouldn't be surprised if he did, I mean he didn't even implement GetFilePathList (or whatever that new function introduced in pre6 was callled) even though he listed it as a new addition.
Did you use ObjSound_Load? Beyond that I think I'll have to take a look in your code for detailsYes, I did. However, the sound object is created in a package script and stored into common data.
You can contact him. Anyone can contact him. Over in LOCAA, we tend to just have one person collect bug reports from the other users and put it all under his name. Usually, that person is Ultima.
---
The way I do it in Digital Earth: Contest is like so:
I use User Events to notify the package script from the stage scripts.
Each time the package script receives a notification, the sound will be played. That means, the package script's @Event will contain the code for calling ObjSound_Play, instead of the stage script.
I already contacted mkm about my GetFilePathList() request not actually being implemented. He said that the function was named GetFileList() and that it will get its intended name in the next update.I was asking about the inability to choose an encoding for reading from text file objects.
I was asking about the inability to choose an encoding for reading from text file objects.
ObjFileB_SetByteOrder()
ENDIAN_LITTLE:リトルエンディアン
ENDIAN_BIG:ビッグエンディアン
ObjFileB_SetCharacterCode()
CODE_ACP:ANSI (Shift-JIS)
CODE_UTF8:UTF8
CODE_UTF16LE:UTF16LE
CODE_UTF16BE:UTF16BE
Code: [Select]ObjFileB_SetByteOrder()
ENDIAN_LITTLE:リトルエンディアン
ENDIAN_BIG:ビッグエンディアン
ObjFileB_SetCharacterCode()
CODE_ACP:ANSI (Shift-JIS)
CODE_UTF8:UTF8
CODE_UTF16LE:UTF16LE
CODE_UTF16BE:UTF16BE
I'm pretty sure there's no difference between a text file and a binary file.
Indeed they do, currently there is no way to change the reading for normal text files. You can try asking mkm about it however, it may not be implemented right away. Requests like those tend to get added to what we in locaa call "the list". Its pretty big and contains many requested functions that have not been implemented, or bugs that have not been fixed yet. Informing mkm about it is still worth a try, if it wasn't for people requesting specific visual effect capabilities (all added to "the list") we may not have had HLSL implemented.
You may have to find some clever workaround in order to achieve what you want, what that is, I can't help there.
3: Archive files save the file path to the directory as if the files were not compressed, and the archive file was a folder. Danmakufu doesn't check by filename alone, it checks the file path exactly. You cannot however, compress different archives into one big archive. The tool itself works as a lock to prevent others from touching resources, there is some compression but it isn't anything big.
The second issue isn't really a coding issue, although it may be. In Touhou games, we've seen a form of "music syncing," like the midboss popping out at the most exciting part of a song. I did that for the first stage of the game, and it worked fine, until testing it on my friend's computer. The boss came 2-3 seconds late on his computer, but it syncs perfectly on mine. Something is causing one of us to go either too fast, or too slow. I have two dropbox links to show you what I mean (I'm Justin, friend is Cam): http://bit.ly/STG1CamVer and http://bit.ly/STG1JustinVer
Something I may have narrowed it down to was that he's running Win 8.1, and I'm running Win 7. Just a theory, though.
If it's an FPS issue, then the only way to guarantee anything is to have your music synced to 60 FPS and your script optimized as well as possible. Of course, you should make sure that the people playing your game have decent computers that are as good as yours or better, and are not having too many programs open while running Danmakufu.What you mean by syncing to 60 FPS is playing the game at 60 FPS and seeing what happens, yes?
What you mean by syncing to 60 FPS is playing the game at 60 FPS and seeing what happens, yes?
Also, optimization- How so? Should I unload graphics when not needed (i.e the splash icon I have appearing before the stage starts- is simply deleting the object enough?)
As always, I appreciate the assistance.
Assume that the script should run at a constant FPS. Preload all boss scenes, sounds, and textures before playing the music. Short circuit your boolean expressions. Remove unneeded variables. Whatever you can do to make your game run at the intended 60 FPS on lower-end computers.
Sparen is basically saying that your friend's computer might not run your game without lag, which would desync the music. He's giving you ways to reduce the potential lag as much as possible.Thank you to the both of you!
I've asked mkm about it some time ago, he said to try using japanese in whatever you post due to the spam protection seeing english as spam, such as including 東方弾幕風. I've tried it, but no success either.
Tried including Japanese first and then only the Japanese, and it still returns a 403.
Mkm's BBS denies all non-Japanese IPs. To get on their board, you need to use a Japanese Proxy or Japanese IP.
I assume you are already in the board and having difficulties to post the msg?
Yes. If that applies, then I'd gladly let someone else report the bug.Since you said 403 I am confused. If you get a 503 it is due to not having Japanese IP. If you are on the board and unable to post make sure you fill out the e-mail and a "edit post" password. Also http is not allowed but that will throw you an error message to edit out the urls.
Since you said 403 I am confused. If you get a 503 it is due to not having Japanese IP. If you are on the board and unable to post make sure you fill out the e-mail and a "edit post" password. Also http is not allowed but that will throw you an error message to edit out the urls.
Has anyone been able to report the file I/O bug I mentioned yet? The success of my project depends on it.
Has anyone been able to report the file I/O bug I mentioned yet? The success of my project depends on it.
If you can't use Text File Objects, use a workaround.
Hey everybody !Oh quite the challenge you're taking here. I think I need to first poll your experience: Did you make any custom effects or worked with sprite objects before?
I would like to know if someone could help me ! I don't really know how to make 3d background...and I really need to make 3d background for my game.
// Load your texture
let floorTex = etc...;
@Initialize {
renderStage;
}
@MainLoop { yield; }
@Finalize { }
// Your sprite, placed in 3D
function makePanel(posX,posY,posZ,angleX,angleY,angleZ) {
let obj = ObjPrim_Create(OBJ_SPRITE_3D); // <----- Very important to create as 3D sprite!
ObjPrim_SetTexture(obj,floorTex);
Obj_SetRenderPriorityI(obj,20);
ObjRender_SetBlendType(obj,BLEND_ALPHA);
ObjRender_SetAlpha(obj,255);
ObjRender_SetScaleXYZ(obj,1,1,0);
ObjSprite3D_SetSourceDestRect(obj,0,0,512,512);
ObjSprite3D_SetBillboard(obj,false);
ObjRender_SetPosition(obj,posX,posY,posZ);
ObjRender_SetAngleXYZ(obj,angleX,angleY,angleZ);
}
// Main rendering
task renderStage {
// Required to let the engine draw past default 2048. If you make a long stage which has for example textures of 4096 or longer, you need to increase the value.
SetCameraPerspectiveClip(10,4096);
// Camera settings.
SetCameraFocusX(0);
SetCameraFocusY(0);
SetCameraFocusZ(0);
SetCameraAzimuthAngle(0);
SetCameraElevationAngle(16);
// Make a panel at X Y Z position 0 (centre) and flipped around X 90 degrees (floor)
makePanel(0,0,0,90,0,0);
}
Can anyone explain the details of GetTransitionRenderTargetName? I know what it does at the basic level, but I need to know about the details such as what it captures and what it doesn't.
Edit: what the heck Danmakufu (http://i.imgur.com/3WO9Wuf.png) (large image)
Edit 2: How do I respawn a player after she's run out of lives? Or do I need some workaround such as having 0 lives = game over?
case(EV_PLAYER_SHOOTDOWN){//To disable continue system, block comment this case.
if(GetCommonData("Practice",true)==false){//Disables invincibility for practice stages
if(GetPlayerLife<0){//If equals 0, still have a life left (IE using last life)
SetPlayerLife(0.123);//Copied from Arby, should prevent STATE_END. In theory.
ContinueSystem;
}//I pray this works. Correctly.
}
}
Hi!
Is there a (simple) way to know in which direction go a move objet (for example a boss object)?
How to get a backslash in a string?Backslash is the escape character,
why I don't think to this ??Not quite, since that won't work if the object is moving upwards. The angles work like this:
so if angle ?90 the object go left and if angle ?90 the object go right. it's right?
why I don't think to this ??Not necessarily.
so if angle ?90 the object go left and if angle ?90 the object go right. it's right?
How do i remove the filters with Yukari and Tenshi's face in the Celestial Showdown script?
task TPlural {
loop(51) {yield;}
let ex = ObjMove_GetX(objScene);
let ey = ObjMove_GetY(objScene);
ObjEnemyBossScene_Add(objScene, 0, dir ~ "Nonspell1Li_N.txt");
ObjEnemyBossScene_Add(objScene, 1, dir ~ "Nonspell2Li_N.txt");
ObjEnemyBossScene_Add(objScene, 2, dir ~ "Spell1_N.txt");
if(GetCommonData("NextStep", "NULL") == "LETTY") {
ObjEnemyBossScene_Add(objScene, 3, dir ~ "Nonspell1Li_N.txt");
} else if(GetCommonData("NextStep", "NULL") == "LILY") {
ObjEnemyBossScene_Add(objScene, 3, dir ~ "Nonspell2Li_N.txt");
}
ObjEnemyBossScene_LoadInThread(objScene);
ObjEnemyBossScene_Regist(objScene);
while(!Obj_IsDeleted(objScene)){
yield;
}
}
But ObjEnemyBossScene_Add is set at the beginning of the boss and not after the spell.Me again!Maybe if you put the check in a separate script?
I want to make alternative spells depending of which boss is killed (like the prismriver) but I have no idea how to do this.
I try something like that in my plural script where NextStep common data is equal to "LETTY" or "LILY" at the end of the previous spell.
-codehere-
But ObjEnemyBossScene_Add is set at the beginning of the boss and not after the spell.
I try to do that in another task but it don't work.
Any idea please?
Well, Helepolis suggested I take talk about the potential use of ZUN sound effects in scripts here, so here I am. I don't know the full story behind whether the sounds on nico commons are rips or not, or if that's even what the japanese danmakufu scripter are using in their games, but it would appear that the use of ZUN's sound effects in games is not taken as seriously as using other types of data, like art, music, and sprites.What are the conditions though for using these sounds? Are they truly free-to-use and allowed to be used when distributing for free or with a sale? We'll need to indeed figure out that link as you highlighted.
However, I recently remembered that there is another MASSIVE library of sounds for games here: http://osabisi.sakura.ne.jp/m2/
It took me a long time to track this site down, but this is the source of game sound effects for MANY Japanese indie and doujin titles. The Exceed series, Suguri, Touhou Labryinth, Phantasmagoria Trues, Magical Singular Day, Danmakufu ITSELF and many more that I'm probably not aware of all use sounds from this library. As many will note, several of those games were sold. It's very difficult for me to read the terms of use (located here (http://osabisi.sakura.ne.jp/m2/material3.html) I believe) so to avoid any potential translation confusion, perhaps someone here with knowledge of japanese could translate the terms of use? I'm certain that these sounds if useable will be more than enough for many scripters looking for an alternative to official Touhou sound effects.
What are the conditions though for using these sounds? Are they truly free-to-use and allowed to be used when distributing for free or with a sale? We'll need to indeed figure out that link as you highlighted.I'm not quite sure this is the case. I've found nothing myself that indicates that your work needs to be free. All of those games that I just listed use those sounds and many are sold, many of them are pretty well known too. This is why I want a proper translation of the terms on that page.
Edit:
Apparently as far as I could grasp something: Terms of use is "Free to use" as long as your game is free as well. Pretty much like the material my partner found about Dnh players. So unfortunately this is a no-go source for my game.
EDIT: Or even better: Load both scripts and have one of them immediately skip to the end if the condition for the spell is met.Good idea. It works. Thanks.
ObjSprite2D_SetSourceRect(obj, x1, y1, x2, y2);
What is the size of the sprite I get if I have x1 = 0, y1 = 0, x2 = 16 and y2 = 16? It's 16*16 or 17*17?And another really stupid question.
WithCode: [Select]ObjSprite2D_SetSourceRect(obj, x1, y1, x2, y2);
What is the size of the sprite I get if I have x1 = 0, y1 = 0, x2 = 16 and y2 = 16? It's 16*16 or 17*17?
And if I have a picture in 16*16, the up-left pixel coordinates is 0*0 or 1*1? And the down-right is 16*16 or 17*17?
I never understand how it's calculated by danmakufu and I always get some artifacts on the side.
This is not a stupid question at all. It is one of the most infuriating things in Danmakufu.
Along with the first parameter of object functions and the lack of first-class functions. Take your pick of which is the most infuriating, and please try to answer my question while deciding.
@Fluffy8x: I'd kind of like you to expand on what you mean by "most recent screenshot" ... ... It's a bit hard for me to interpret
let las1 = CreateStraightLaserA1(-2*x1+xOffset,y1-3*x1*tan(theta),theta,2000,width,500,8*20+8%8,40);
wait(20);
ObjMove_SetSpeed(las1,3);
it made a bunch of lasers, each moving to the rightlet las1 = CreateStraightLaserA1(-2*x1+xOffset,y1-3*x1*tan(theta),theta,2000,width,500,8*20+8%8,0);
wait(20);
let newX = ObjMove_GetX(las1);
loop(GetStgFrameWidth){
newX = newX+4;
ObjMove_setX(las1,newX);
}
also didn't work. and I had to change the delay to 0 so it would have a hitbox at any point. I just want one solid laser to move after spawning.Sometimes that function gives a screenshot of something else such as the Danmakufu main menu or a previous playthrough. If you want more explanation, then I'll just release 0.03tr to the public.
I make a player shot that pass through enemies an infinite number of time. But I want to do some stuff when it hurt an enemy.I'm not entirely sure if that's exactly possible, sorry. You may want to send a feature request, as that seems to be a good feature to have.
Is there a way to know if the shot is in contact with a enemy and wich enemy?
If your image is 16x16, then you will do ObjSprite2D_SetSourceRect(obj, 0, 0, 16, 16);Code: [Select]ObjSprite2D_SetSourceRect(obj, x1, y1, x2, y2);
What is the size of the sprite I get if I have x1 = 0, y1 = 0, x2 = 16 and y2 = 16? It's 16*16 or 17*17?
And if I have a picture in 16*16, the up-left pixel coordinates is 0*0 or 1*1? And the down-right is 16*16 or 17*17?
I never understand how it's calculated by danmakufu and I always get some artifacts on the side.
having a little trouble with object lasers, I'm trying to make a laser then move it across the screen.A loop will execute in one frame if you don't yield it, so what you're doing, simplified, is actually just setting the X value to 4*GetStgFrameWidth. Add a yield; or wait(1); to your loop, and it will execute the loop one frame at a time, giving movement.
I think you're gonna actually have to render every render priority layer TO the render target beforehand... are you doing so?
Ehh?
Anyone know why GetTransitionRenderTargetName might not get the most recent screenshot of the game that exists?
Sometimes that function gives a screenshot of something else such as the Danmakufu main menu or a previous playthrough. If you want more explanation, then I'll just release 0.03tr to the public.The transition render target is drawn on by menu scripts. By default you'll get the last view of the title screen or the last view of the pause menu, because they draw to that target. The purpose is to get the last view of any scene immediately before the menu script is called. You would use this in a pause menu to render the "paused" game scene while in the menu, for example. How have you been using it?
Me again and again.I'm not sure what gtbot is talking about but ObjCol_IsIntersected() and ObjCol_GetListOfIntersectedEnemyID() are what you want.
I make a player shot that pass through enemies an infinite number of time. But I want to do some stuff when it hurt an enemy.
Is there a way to know if the shot is in contact with a enemy and wich enemy?
16*16. The left and top coordinates are inclusive; the right and bottom coordinates are exclusive.Code: [Select]ObjSprite2D_SetSourceRect(obj, x1, y1, x2, y2);
What is the size of the sprite I get if I have x1 = 0, y1 = 0, x2 = 16 and y2 = 16? It's 16*16 or 17*17?
And if I have a picture in 16*16, the up-left pixel coordinates is 0*0 or 1*1? And the down-right is 16*16 or 17*17?
I never understand how it's calculated by danmakufu and I always get some artifacts on the side.
I'm not sure what gtbot is talking about but ObjCol_IsIntersected() and ObjCol_GetListOfIntersectedEnemyID() are what you want.
// Difficulty scaling, 0 = normal, 1 = hard, 2 = lunatic
task fairyShot00(obj) {
if(GetCommonData("gameDifficulty",false) == 0) {
}
if(GetCommonData("gameDifficulty",false) == 1) {
}
if(GetCommonData("gameDifficulty",false) == 2) {
}
}
To check what the fairy has to use depending on difficulty. Is this a safe and proper way or can it cause complications later on?
Not a question but more like verification whether I am on the right track. I'm about to implement difficulty scaling in my game but I want to know if I set the core structure correctly.
Basically using CommonData to set the selected difficulty thenCode: [Select]// Difficulty scaling, 0 = normal, 1 = hard, 2 = lunatic
To check what the fairy has to use depending on difficulty. Is this a safe and proper way or can it cause complications later on?
task fairyShot00(obj) {
if(GetCommonData("gameDifficulty",false) == 0) {
}
if(GetCommonData("gameDifficulty",false) == 1) {
}
if(GetCommonData("gameDifficulty",false) == 2) {
}
}
This is similar to the system I use for stage enemies. The main concerns I had were:1) Similar thought, I might need to script in debug option ability to test difficulties for beta testers.
-default values - When testing stages (not using a package), I had to manually set the difficulty I wanted in order to test different difficulties
-keeping a standardized default
-having to change code in multiple places - If something goes wrong, you may have to correct it for each and every case.
Thanks Drake and gtbot for the explanations. And ObjCol_GetListOfIntersectedEnemyID() work well :)If you make a non-touhou game without danmakufu ph3/0.12m, then you're not bound to ZUN's Touhou derived fanwork guidelines.
edit:
Another thing.
If I make a non-touhou danmakufu game (with custom and legit ressources), can I share it on steam (or other things like that) for free? Is there some danmakufu use restrictions somewhere?
And can I send non Touhou danmakufu-game? (I don't want but I'm curious about that).
Sorry if there is already an answer somewhere.
Not a question but more like verification whether I am on the right track. I'm about to implement difficulty scaling in my game but I want to know if I set the core structure correctly.
Basically using CommonData to set the selected difficulty thenCode: [Select]// Difficulty scaling, 0 = normal, 1 = hard, 2 = lunatic
To check what the fairy has to use depending on difficulty. Is this a safe and proper way or can it cause complications later on?
task fairyShot00(obj) {
if(GetCommonData("gameDifficulty",false) == 0) {
}
if(GetCommonData("gameDifficulty",false) == 1) {
}
if(GetCommonData("gameDifficulty",false) == 2) {
}
}
I'd prefer using a function to return the game difficulty, and branch only for radically different behavior.
Fluffy. GetCommonData("gameDifficulty",false) is a function that returns the game difficulty. He is branching for different behavior.
Fluffy. GetCommonData("gameDifficulty",false) is a function that returns the game difficulty. He is branching for different behavior.
function GetDifficulty()
{
return GetCommonData("gameDifficulty",0);
}
I find it quite likely that you're limited to the scope of doujin works by using Danmakufu, and unless clearly told otherwise you should not assume anything more than that.
Not a question but more like verification whether I am on the right track. I'm about to implement difficulty scaling in my game but I want to know if I set the core structure correctly.
Basically using CommonData to set the selected difficulty thenCode: [Select]// Difficulty scaling, 0 = normal, 1 = hard, 2 = lunatic
To check what the fairy has to use depending on difficulty. Is this a safe and proper way or can it cause complications later on?
task fairyShot00(obj) {
if(GetCommonData("gameDifficulty",false) == 0) {
}
if(GetCommonData("gameDifficulty",false) == 1) {
}
if(GetCommonData("gameDifficulty",false) == 2) {
}
}
Would that then mean that the removal of the default images from the game's distribution and the usage of ONLY the engine and no base assets would allow for the touhou derivative tag to be removed? I agree that its best to ask mkm directly but just throwing that out there.Perhaps, and I was going to mention this, but if you do so without asking it just makes it seem as though you're trying to loophole.
I don't think this is the case, I had asked mkm personally about selling a game made in Danmakufu (I didn't specify if it was Touhou on purpose), he simply replied that he was ok with it. I don't recall the documentation making a note of it either. So I personally will assume that non Touhou works are free of those limitations. I don't think mkm would enforce such things, if he was really serious about it, they would be mentioned (he would've made some extra attempt to mention it in the email as well).You can sell doujin games just fine. We're talking about putting it on Steam, specifically, not just selling it. Again, publishing is very likely a topic that doesn't ever show up. Using game data is a much more pertinent topic and probably causes issues even within the Japanese fandom, but commercialization is not. The point is that it's best to err on the side of caution.
I'm not sure what gtbot is talking about but ObjCol_IsIntersected() and ObjCol_GetListOfIntersectedEnemyID() are what you want.Just want to highlight this doesn't work for sprite Objects. I've been busy with my own Reimu's Musou Tensei spell card where I need to check if her Yin Yang ball is colliding, but it isn't triggering.
Just want to highlight this doesn't work for sprite Objects. I've been busy with my own Reimu's Musou Tensei spell card where I need to check if her Yin Yang ball is colliding, but it isn't triggering.Collision objects are really just the objects that you'd think would have collision detection by default. So yeah, enemies, shots and lasers, possibly players and items as well, etc.
Wiki doesn't specify which objects it listens to. I believe it was similar with the Obj_Obj intersected functions. They only listen to Enemy objects and Shot objects.
This is quite troublesome.
Edit:
Even worse, IsIntersected_Obj_Obj(obj1,obj2) isn't working either. Only for lasers and bullets (that is stated on wiki)
GetObjectDistance(obj1,obj2) worked for my sprite yin yang ball. if(GetObjectDistance(obj1,obj2) < 8 ) { // do stuff } <- if the distance between 2 objects is smaller than 8 pixels, it will do stuff.
Unless someone has a better and easier solution.
like I don't know what collision radius it uses to detect the collision (it can't be just comparing the coordinates cause they'll virtually never be exactly the same). It might use the shot or enemy's hitbox size as set by other functions, I just don't know for sure.That's very likely the case. It would use DNH's internal collision system, and I would expect that only objects with defined collision properties are affected, hence why it's undefined for objects that don't collide. Because of this I would also expect non-registered enemies, bullets, and so on to not be counted, and is why I expect player and item objects to count. However, I'm not sure whether or not "collisions" between certain types are considered valid, like players to player shots, or enemy shots to player shots, or even enemies to enemies.
//////////////////////////////////////////
//Librairie de fonction pour les ennemis//
//////////////////////////////////////////
task Shot1(enemyid,x,y,angle,g,v)//Tir basique avec effet d'apparition
{
let shot_obj = ObjShot_Create(OBJ_SHOT);
let alpha = 0;
let sx = 4;
let sy = 4;
ObjShot_Regist(shot_obj);
ObjShot_SetAutoDelete(shot_obj, true);
ObjMove_SetPosition(shot_obj,x,y);
ObjMove_SetAngle(shot_obj,angle);
ObjShot_SetGraphic(shot_obj, g);
ObjMove_SetSpeed(shot_obj,v);
ObjRender_SetAlpha(shot_obj,alpha);
ObjRender_SetScaleX(shot_obj, sx);
ObjRender_SetScaleY(shot_obj, sy);
if(Obj_IsDeleted(enemyid)==true){Obj_Delete(shot_obj);}
loop(20)
{
ObjRender_SetAlpha(shot_obj,alpha);
ObjRender_SetScaleX(shot_obj, sx);
ObjRender_SetScaleY(shot_obj, sy);
sx -= 0.3135/2;
sy -= 0.3135/2;
alpha +=25.5;
loop(0.3){yield;}
}
}
task Shot2(enemyid,x,y,angle,g,v)//Tir basique avec effet d'apparition + effet ralentit
{
let shot_obj = ObjShot_Create(OBJ_SHOT);
let alpha = 0;
let sx = 4;
let sy = 4;
ObjShot_Regist(shot_obj);
ObjShot_SetAutoDelete(shot_obj, true);
ObjMove_SetPosition(shot_obj,x,y);
ObjMove_SetAngle(shot_obj,angle);
ObjShot_SetGraphic(shot_obj, g);
ObjMove_SetSpeed(shot_obj,v);
ObjRender_SetAlpha(shot_obj,alpha);
ObjRender_SetScaleX(shot_obj, sx);
ObjRender_SetScaleY(shot_obj, sy);
if(Obj_IsDeleted(enemyid)==true){Obj_Delete(shot_obj);}
loop(20)
{
ObjRender_SetAlpha(shot_obj,alpha);
ObjRender_SetScaleX(shot_obj, sx);
ObjRender_SetScaleY(shot_obj, sy);
sx -= 0.3135/2;
sy -= 0.3135/2;
alpha +=25.5;
loop(0.3){yield;}
}
loop(5)
{
ObjMove_SetSpeed(shot_obj,v);
v--;
loop(4){yield;}
}
}
Question regarding TextObjects and setting text.
For debugging purposes, I was wondering if it is possible to combine string and integer in one line? For example ObjText_SetText(obj, "location X:" bossX); So the result on my screen becomes: "Location X: 24"
Of course the above will toss an error back at you because it needed a special method. I remember something vaguely done in the old engine but tracking down old threads I couldn't find it any more so decided to ask again.
Never heard of it. You need to use IntToString and string concatenation.How to perform the string concatenation? Can ya show an example with the above?
How to perform the string concatenation? Can ya show an example with the above?
ObjText_SetText(obj, "location X: " ~ IntToString(bossX));
How to perform the string concatenation? Can ya show an example with the above?To expand on Fluffy's response, concatenation of strings means that you're joining one string with another. The way that is done is with ~. For example, if I have two strings, "Hi my name is" and "ExPorygon" writing "Hi my name is" ~ "ExPorygon" will result in the combining of the two, end to end: "Hi my name is ExPorygon"
you can also use the actual concatenate(array1,array2) function or the append(array,value) function
Would be useful if Danmakufu had first-class functions.
Danmakufu supports that. It's all about how you use them.
but strings are simply arrays of characters
i.e. "melon" = ['m','e','l','o','n'] so it of course is valid for string concatenation.
ph3:
'a' + 0 = type error
['a' + 0] = [97]
['a']+[0] = type error
'a' + 'b' = type error
['a' + 'b'] = [195]
"a" + "b" = ?
0.12m:
'a' + 0 = 97
['a' + 0] = [97]
['a']+[0] = type error
'a' + 'b' = 195
['a' + 'b'] = [195]
"a" + "b" = テ
case(EV_PLAYER_SPELL){
loop(120){
AddGraze(1);
yield;
}
}
Yeah, that quirk mostly has to do with characters being treated as their codepoints. It gets pretty silly, since it doesn't seem consistent on how it's applied. In 0.12m it was mostly consistent that characters were treated as numbers for arithmetic, which also meant adding zero gave you the codepoint, for example. In ph3 you get type mismatches... unless you wrap it in an array first. Doing vector addition gives more type errors. In both 0.12m and ph3 having characters and numbers in an array gives type errors.Code: [Select]ph3:
'a' + 0 = type error
['a' + 0] = [97]
['a']+[0] = type error
'a' + 'b' = type error
['a' + 'b'] = [195]
"a" + "b" = ?
0.12m:
'a' + 0 = 97
['a' + 0] = [97]
['a']+[0] = type error
'a' + 'b' = 195
['a' + 'b'] = [195]
"a" + "b" = テ
The "wrong" example you give is basically because doing arithmetic turns the characters into numbers, despite still being able to be displayed as characters.
I've been developing a Danmakufu script over the past week or so, and I've encountered a strange bug.
I have the boss firing two shots left and right, which are intended to bounce at the player when they hit the wall, but they... don't.
Despite the fact that I have code for that in place which is really odd.
Here's my code, for reference. (http://pastebin.com/f3hmzfkx)
task BulletCommands(obj){
while(<insert code for inside walls here>){yield;}
ObjMove_SetAngle(obj, GetAngleToPlayer(obj);
}
to work better. Also, use GetStgFrameWidth and GetStgFrameHeight instead of 384 and 448.What is the limitations of Danmakufu? I am very new and although I wanna learn Unity I am worried I am walking through a land mine so if danmakufu is recommended for beginners and the limitations are not too bad I might use it to practice. (Please be the right thread I am sorry if it isn't I am trying)
I wouldn't call most of those limitations, really. Not having arbitrary features in the language specification isn't a real limitation, I think. Noting a lack of features in the language makes sense when the language probably should support a capability because of its relation to another capability but doesn't, or where something should be accessible but isn't. Not being able to curry functions in a procedural language isn't something to lose sleep over.
- Speed is a concern, although really it doesn't get bad until you start doing a serious amount of work. On the level of fully polished games you will probably have to be careful and optimize.
- The type system is quite weak, as the only "raw" types available to you are boolean values, numbers (only one datatype) and characters (arrays of which are strings). Many things you manipulate in Danmakufu are various types in the program itself but the scripting language only lets you refer to them with numbered IDs (object IDs, enemy IDs, etc).
- The only data structures available are arrays (which really behave more like lists), so you have to implement other structures yourself if you need to. Map structures are sort of available in the form of object "values" and CommonData, but it's fairly clunky.
- There are many things the engine does in the background that would be really nice to be able to access but you have no way to, so some things are just plain hidden from you. This has improved since 0.12m, but still isn't as good as it could be.
- Although there are objects and most of your programming is about manipulating them, the object-oriented language features are very limited both in what you can access and how you access them. Again, better than it was in 0.12m, but still very limited when compared to using libraries on top of more feature-rich programming languages.
(- Anonymous functions would be nice considering how many tasks you write in DNH are just going to be run the next line anyways.)
Mainly I'm wondering what FallenLegacy expects as examples of limitations, and what they expect to be able to do, if this is one their first programming experiences.
So in other words it is not for beginners and I am better off with Unity or UDK til I know what I am doing? These issues you stated sound complex to fix.
You can, it'll just crash if you notify the same event without changing conditions. I can't really think of scenarios where an event just won't register at all, since if you use NotifyEventAll() and any script is running, it'll run at least some @Event routine. Whether it's handled after that is another matter.
@Event {
alternative (GetEventType())
case (EV_START_BOSS_SPELL) {
let path = dirCurrent ~ "system_magic_circle.dnh";
let id = LoadScript(path);
StartScript(id);
}
case (EV_GAIN_SPELL) {
let objScene = GetEnemyBossSceneObjectID();
let score = ObjEnemyBossScene_GetInfo(objScene, INFO_SPELL_SCORE);
TGainSpell(score);
}
case (EV_SUBMIT_COMPLETE) {
if (GetPlayerLife != 0.123) {
NotifyEventAll(EV_SUBMIT, [getCharacter, getDifficulty, isHidden, 12, GetScore]); // EV_SUBMIT = EV_USER + 6
while (!GetCommonData("HSSubmitDone", false)) {WriteLog("poop"); yield;}
SetCommonData("HSSubmitDone", false);
}
}
}
@Event {
alternative (GetEventType)
case (EV_USER + 3) {
let path = GetEventArgument(0);
ObjSound_Stop(bgm);
if (path != "") {
ObjSound_Load(bgm, path);
ObjSound_Play(bgm);
let dPath = SplitString(path, "/");
SetAreaCommonData("Cy05", "HeardBGM " ~ dPath[length(dPath) - 1], true);
}
}
case (EV_USER + 4) {
let p = GetEventArgument(0);
if (p) {
TBackground;
}
else {
TStopBG;
}
PauseStageScene(p);
}
case (EV_USER + 5) {
whenYouAreDedz(GetEventArgument(0));
}
case (EV_USER + 6) {
RaiseError("event intercepted"); // <--!!
viewHS(GetEventArgument(0));
}
}
Output GetEventType() somewhere at the start of an @Event routine to dump all the events that happen. Are you sure EV_SUBMIT_COMPLETE triggers?
2015/02/15 01:36:25.753 1000007pack
2015/02/15 01:36:25.772 1000007sys
2015/02/15 01:36:25.783 1000006sys
// Enemy or boss invul mode (since 0.12m doesn't have one)
task setInvulnerableTime(obj,t) {
// Get damage rate values from obj and store in vars.
let lockShotDmgRate = ObjEnemy_GetInfo(obj,INFO_DAMAGE_RATE_SHOT);
let lockSpellDmgRate = ObjEnemy_GetInfo(obj,INFO_DAMAGE_RATE_SPELL);
// Set damage rate to 0,0.
ObjEnemy_SetDamageRate(obj,0,0);
// yield for t-frames (similar to wait)
loop(t) { yield; }
// Reset damage rates to initial.
ObjEnemy_SetDamageRate(obj,lockShotDmgRate,lockSpellDmgRate);
}
task bullet(.....) {
while() {
if(bullet hits "ceiling/floor") {
> Change angle 90 degree exact horizontal (so it goes up or down)
}
if(bullet hits "walls") {
> Change angle 90 degree exact vertical (so it goes up or down)
}
}
}
function GetNeatoLockAngle(angle){
return [round(angle/90)*90 , round((angle%90)/90)*-180+90];
}
Why is This (http://pastebin.com/bSiMecLL (http://pastebin.com/bSiMecLL) ) creating this (http://imgur.com/tIhhU1I (http://imgur.com/tIhhU1I))?You're calling TFire; in the @MainLoop thread. MainLoop runs continuously, which means every frame, TFire is summoned and thus causing that what you're showing us.
Why is ObjSprite2D_SetSourceRect(objRumia,64,1,127,64); not activating here? Rumia isn't switching back to her idle position. (http://pastebin.com/m8phaq9d (http://pastebin.com/m8phaq9d))
Also, why is this (http://pastebin.com/DSyUgsGY (http://pastebin.com/DSyUgsGY)) giving me an error at line 13 saying it can't comprehend it? o.0
x = (x*0.95)+(GetPlayerX*0.05);
y = (y*0.95)+(GetPlayerY*0.05);
Hi ! I wanted to ask :
Is there a way to make each bullets (ObjShot) which have spawned at different frames change their speed at the same frame ? And how please ?
Unless I'm misinterpreting your question, I believe Obj_SetValue and Obj_GetValue would be what you're looking for.. . . . . :derp: :derp: :derp: :derp:
Dump them into an array and then when you want them to change their speed, iterate through the array and use Obj_SetSpeed
Alternatively, count how many frames are passing between their spawn times and use ObjMove_AddPattern with a speed shift, but set the frame parameter in such a way that they all change at the same time.
Since I'm not very good with arrays, the second method seems to work best for me, thank you ! :3
CreateItemA2(ITEM_POWER, GetPlayerX, GetPlayerY, GetPlayerX+90*cos(adest), GetPlayerY-ydest+24*sin(adest), 100);
(adest & ydest are variable used to set the final item position).Hi! I have some questions about the item functions.
I want to create some power item. So i use CreateItemA2 (there are created at the player's death) with something like that:Code: [Select]CreateItemA2(ITEM_POWER, GetPlayerX, GetPlayerY, GetPlayerX+90*cos(adest), GetPlayerY-ydest+24*sin(adest), 100);
(adest & ydest are variable used to set the final item position).
I get some beautiful power item but without any effect on the Player poser value. Same thing with 1UP items (and BOMBS item I guess...).
How this thing works? What I doing wrong/notdoing?
I see I can use user defined item or item script but I dont even know hom I'm supposed to use this.
if(frame == 7) {
SE(laser02_path);
CreateStraightLaserA1(ex, ey, A+1, 800, 20, 80, C_LASER_RED, 60);
A += alt*360/(64);
}
if(frame == 8) {
SE(shot01_path);
CreateStraightLaserA1(ex, ey, A+1, 800, 20, 80, C_LASER_RED, 60);
Laser01(ex, ey, 4, A+5, 180, 24, LIGHTNING_RED, 30);
frame = 6;
A += alt*360/(56);
if((|A|) >= 360) {
alt = -1*alt;
A = 0;
frame = -360+20*step;
step++;
if(step > 6) {step = 6;}
ObjMove_SetDestAtSpeed(objBoss, rand(60,260), rand(60,130), 1.5);
}
}
This is the laser's part of the script. It's the same laser as the others but it is the only one that does not work properly. Why? So it just another danmakufu joke ok. Thank you :)
If you're talking about the upper right hand corner, with no lasers, that's your code, on the other hand.Nope. I just take the screenshot before the upper right hand corner's laser spawn ;).
How are numbers stored in Danmakufu? It seems to store them as doubles, but surprisingly (0.1 + 0.2 - 0.3) * 10^16 returns zero.
Hi!
I have some serious FPS drop in my current script (and in all my script -_-) but I don't really know why except that I'm not a good scripter.
So, what can be the possible main sources of heavy FPS drop and what are things to do or not do to avoid this kind of issues? Most scripteur here do awesome things whitout lag so I have to do something wrong :/
I'm a bit desperate...
Hi!To expand and explain Sparen's post:
I have some serious FPS drop in my current script (and in all my script -_-) but I don't really know why except that I'm not a good scripter.
So, what can be the possible main sources of heavy FPS drop and what are things to do or not do to avoid this kind of issues? Most scripteur here do awesome things whitout lag so I have to do something wrong :/
I'm a bit desperate...
task SE(path) {
let obj = ObjSound_Create;
ObjSound_SetSoundDivision(obj,SOUND_SE);
ObjSound_Load(obj,path);
ObjSound_Play(obj);
ObjSound_SetVolumeRate(obj,100);
loop(400) {yield;}
Obj_Delete(obj);
}
If it's across your entire script, then you may have to do some serious fixing.On my computer it run at 60 fps all the time exept in some case like when I use a bomb or when a spellcard is declared. But on other's computer it seem to run at ~50 fps all the time (like on your's if I trust your RaNGE video of my entry). It's a bit hard to know if it really fixed or not :/
- It seem that sound object add fpsdrop in some case. I use a task like that to do sound effect but I'm not sure it's the best thing to do:Code: [Select]task SE(path) {
let obj = ObjSound_Create;
ObjSound_SetSoundDivision(obj,SOUND_SE);
ObjSound_Load(obj,path);
ObjSound_Play(obj);
ObjSound_SetVolumeRate(obj,100);
loop(400) {yield;}
Obj_Delete(obj);
}
function SE(path) {
let obj = ObjSound_Create;
ObjSound_SetSoundDivision(obj,SOUND_SE);
ObjSound_Load(obj,path);
ObjSound_Play(obj);
ObjSound_SetVolumeRate(obj,100);
return obj;
}
let SE_SHOT;
let SE_CHARGE;
function LoadSE(path) { // Returns a Sound object that plays the given file
let obj = ObjSound_Create();
ObjSound_SetSoundDivision(obj, SOUND_SE);
ObjSound_Load(obj, path);
ObjSound_SetVolumeRate(obj, 100);
return obj;
}
@Initialize{
SE_SHOT = LoadSE(dir ~ "shot.wav");
SE_CHARGE = LoadSE(dir ~ "charge.wav");
}
task TPattern(){
loop{
ObjSound_Play(SE_CHARGE);
loop(60){yield;}
loop(60){
ShootBullets();
ObjSound_Play(SE_SHOT);
yield;
}
loop(240){yield;}
}
}
- I use a general task to load all the textures and sound at the beginning of my stage script but... it load the texture for all the scripts that will be called later (like boss scripts, item scripts, system script, etc) or it load the texture for this script only? I use the Texture part of the log windows and I see texture that appear several times. But I'm not sure if there are loaded texture of used texture...If you're seeing textures with the same (full) name but at different addresses, something isn't right. The number of different places that the texture is being used is under the Ref column, so that's what should be increasing.
If you're seeing textures with the same (full) name but at different addresses, something isn't right. The number of different places that the texture is being used is under the Ref column, so that's what should be increasing.Thanks, thanks and thanks again. I found my main problem whit that. I fail my texture/sound load and it load I don't know what at the beginning and load the use thing when it is used... everytime).
Is in ph3 some "event_script{} " like in 0.12m.
I want to make dialogue?or schould I do all this stuff with Prim-objects or graphic? :V
Is in ph3 some "event_script{} " like in 0.12m.
I want to make dialogue?or schould I do all this stuff with Prim-objects or graphic? :V
You can use text objects.
SetAreaCommonData("core","Normal",[
[[0,0,0],[0,0,0],[0,0,0],[0,0,0]],
[[0,0,0],[0,0,0],[0,0,0],[0,0,0]],
[[0,0,0],[0,0,0],[0,0,0],[0,0,0]],
[[0,0,0],[0,0,0],[0,0,0],[0,0,0]],
[[0,0,0],[0,0,0],[0,0,0],[0,0,0]],
[[0,0,0],[0,0,0],[0,0,0],[0,0,0]]
]);
...
@Event{
runEvent;
}
...
Example Separate Scripttask runEvent{
alternative(GetEventType())
case(EV_REQUEST_LIFE){
SetScriptResult(1500);
}
case(EV_REQUEST_TIMER){
SetScriptResult(60);
}
}
You don't use a task; @Event is already a routine that runs every frame an event occurs, so there's no purpose in creating an extra thread for it. It'd be even worse if you had looping yields in it, since not only does @Event not even run every frame, but it would also spawn that task every time an event occurred, which would be hilariously bad.*facepalm* When I said task, I meant function. Whoopsy me >n<
The answer is yes, but just use a function/subroutine instead. In most cases this is a bit iffy just because you don't usually want to have the same events and results for every script, but if it works for you then sure.
I have a question regarding the User Interface and Replay system for ph3. I know in particular the Locaa folks are far more advanced and experienced with the UI and replay system so hoping they might teach me in this. I have studied and made menu system for the game but the replay system seems to be confusing the hell out of me.
Studying Rumia's sample and digging through the endless acronyms and style isn't helping. In desperation I was considering on temporary copy-pasting Rumia's method and crediting (if I were to run out of time), but since there is some time left I was wondering if it is able to get done in a fashionaaabluh way.
I have honestly no idea where to start with the replay saving screen + Replay listing screen. Could perhaps someone explain me which essential functions I need to use or what the actual "structure" is for a replay save / display / load menu?
Thanks
InitializeStageScene;
SetStageIndex(stgIndex);
SetStageMainScript("stagescript.txt");
SetStagePlayerScript;
StartStageScene;
I've got another question (and this one might seem silly):CommonData is a function which allows you to communicate across scripts (mainly) or tasks/functions which aren't included/related directly in ph3. Normally you would need to include scripts to call variables from there (if global). CommonData is stored in the "memory" during the entire "play" and is active once it is called/set.
What is CommonData, what is it used for and how is it used?
I'm trying to learn aspects of Danmakufu and this one feels important to learn, but the wiki isn't helping me on the subject.
SetCommonData("playerPower",100);
// player picks up a P.
let power = GetCommonData("playerPower",0);
power++;
SetCommonData("playerPower",power);
@Event {
alternative(GetEventType())
case(EV_REQUEST_IS_DURABLE_SPELL) {
SetScriptResult(true);
}
}
Does not return 'true' when I check ObjEnemyBossScene_GetInfo(bossObj,INFO_IS_DURABLE_SPELL) with text object. Am I missing something?
Edit quick question
Has anybody ever fiddled with INFO_IS_DURABLE_SPELL ? This:Code: [Select]@Event {
Does not return 'true' when I check ObjEnemyBossScene_GetInfo(bossObj,INFO_IS_DURABLE_SPELL) with text object. Am I missing something?
alternative(GetEventType())
case(EV_REQUEST_IS_DURABLE_SPELL) {
SetScriptResult(true);
}
}
Try setting the time limit as well.There is one, I removed it in the post for display reasons but guess that wasn't a good idea. (There was also a life result)
There is one, I removed it in the post for display reasons but guess that wasn't a good idea. (There was also a life result)What about the spell bonus?
What about the spell bonus?Negative. Funny thing is: If I set a spell bonus score, and try to retrieve that value it doesn't report it either. But if I capture the card, it will show the spell bonus I set with the default system.
Negative. Funny thing is: If I set a spell bonus score, and try to retrieve that value it doesn't report it either. But if I capture the card, it will show the spell bonus I set with the default system.
Edit
Never mind, figured it out when I realised I had used the INFO_TIMER before in my SpellCircle code: ObjEnemyBossScene_GetInfo(GetEnemyBossSceneObjectID,INFO_TIMER);
The magical missing value here is GetEnemyBossSceneObjectID which will retrieve the bossSceneID and then the function becomes usable. bossObj is wrong because that is the enemy boss obj. Also retrieving the scene id with commondata caused ph3 to freeze.
Now I can see that my debug text throws " true " for the DURABLE_SPELL result.
Yeah, I need some help with Danmakufu and AppLocale.
So, what will happen if I open Danmakufu without Applocale?
Also how do I install AppLocale? Willl it change my computer system and... <Insert More questions here>?
What's the current format of the map? Depending on what you're trying to get from the map a solution would vary.
....................................
....................................
....................................
....00000.............#.............
....00000.............#.............
....00000...........#####...........
....00$00...........#...#...........
......*.............#...#*..........
......#.............#....$000.......
......#.............#....0000.......
......#.............#....0000.......
......#.............#...............
......#########...00000.............
......#.......#...00000.............
......#.......###*$0000.............
So I am trying to load a 2D map from a text file. However, I do not how to load this into a 2D array in Danmakufu, as there do not seem to be ObjFile functions that can read individual characters from a text file.
Would it be best to write a C program to convert my text file to a binary one and then use ObjFileB_ReadByte() to obtain the character values in the map so that I can process and load them into a 2D array? Or is there a O(n^2) or better alternative solution?
Hello, i'm really new on danmakufu (I know some programming language [C#, Java, VB, PHP, JS] but this is new to me, so, i'm a newbie) and i know how to do basic stuff but of course, everything looks great if you do great so, to the point:
I want to know how to put a BG on movement in a Spellcard and also how to do a hp bar similar to TH13 hp bar. I know the basic i do some... simple spellcards (Sparen tutorials, Helepolis tutorials too) but i want to this thing look more... "touhouness"? That's the think, thanks everyone and hope somebody can help me out :D
Thanks to everyone, the last topic it's really helpfull, but thanks to everyone, i still a little confuse about the Background Imag of the spellcard, so, i make a 3D render of the image and use in the system?You can draw 3D backgrounds anywhere you like. Most people follow the samples and just call a separate script with a bunch of 3D background code stored in it with the #Background[path] header
This is a question that may have no answer.
When using a render object or any non-vector graphic in Danmakufu phd (it did not exist in 0.12m), there is anti-aliasing, which blurs the edges of images. However, when pixel perfect precision is wanted, there is, as far as I know, no way to turn this off and keep the original pixels of the source image. Is there a way to turn off anti-aliasing in Danmakufu? If there is a solution involving shaders, I will consider it.
Its not anti-aliasing, or even close to what AA even does. The problem is that your texture's width and height are not a power of 2. This is a feature that DirectX9 has that will resize images that are not a power of 2 (n^2), which causes the image to be blurred and distorted.
You can use a x2 picture and keep pixel without blur if it don't move. But on moving picture it remain some very light blur pixels on the edges. It can work if you want a pixel perfect background or HUD and keep a blur tolerance on characters and bullets.
Its not anti-aliasing, or even close to what AA even does. The problem is that your texture's width and height are not a power of 2. This is a feature that DirectX9 has that will resize images that are not a power of 2 (n^2), which causes the image to be blurred and distorted.This actually isn't entirely true. Yes, you do have to use images of dimensions 2n due to the aforementioned reason. Additionally though, the reason why moving pictures are blurred is largely due to rendering at non-integer positions. Even if you're drawing a sprite at a fixed location, but non-integer, it will also get blurry aids from interpolation gimmicks (not AA).
However, when pixel perfect precision is wanted, there is, as far as I know, no way to turn this off and keep the original pixels of the source image. Is there a way to turn off anti-aliasing in Danmakufu? If there is a solution involving shaders, I will consider it.There's a solution for Primitive objects. Unfortunately I haven't found a way to perfectly render things like Shot objects without introducing fairly significant overhead.
function ObjSprite2D_Clean(obj, l, t, r, b){
let hw = (r - l) / 2;
let hh = (b - t) / 2;
let a = ObjMove_GetAngle(obj);
let s = ObjMove_GetSpeed(obj);
let off_x = (ObjRender_GetX(obj)+cos(a)*s)%1;
let off_y = (ObjRender_GetY(obj)+sin(a)*s)%1;
ObjSprite2D_SetDestRect(obj, -hw - off_x, -hh - off_y, hw - off_x, hh - off_y);
}
...Except that the texture is 512x512.
//Initializes a Tile Object
//Param: Grid X (int), Grid Y (int)
//Return: Object ID (int)
function ObjTile_Create(x, y){
let obj = ObjPrim_Create(OBJ_SPRITE_2D);
ObjTile_SetPosition(obj, x, y);
ObjRender_SetPosition(obj, x*24, y*24, 1);
return obj;
}
Dunno what you're doing, but this works just fine.
https://gist.github.com/drakeirving/f49aeb16fc0f9c8ac331
I dunno if it'll be of help, but perhaps the issue could be related to the Stage width/height? Or perhaps the window of Danmakufu isn't at its standard 640x480. If not those little thing, then I guess I'm of no help. Just figured I'd put my 2-cents worth in
case(RESULT_SAVE_REPLAY) {
ObjText_SetText(stglist2,"SAVE REPLAY was chosen");
loop(120) { yield; }
TerminateStageScene;
gameReplaySaveScene;
break;
}
I even delayed the thing to see if the correct case was called. It was, so we can assume my menu choice is correctly passed through. gameReplaySaveScene is basically task that summons the replay list and allows the player to select a replay slot. This same menu is exactly called when you Game Over. So to sum up:Sorry please, if this question was already here, aaand maybe it is stupiest question,,,but how to make enemy (boss) float? (by Y goes up and down a little). I tried various way, but enemy started to behave weird?Use ObjSprite2D_SetDestRect(); and modify the ' top ' and ' bottom ' rect parameters so the Y-position of the sprite shifts. This way you won't be moving your actual Obj position and thus avoid weird behaviour.
Use ObjSprite2D_SetDestRect(); and modify the ' top ' and ' bottom ' rect parameters so the Y-position of the sprite shifts. This way you won't be moving your actual Obj position and thus avoid weird behaviour.
Example for 64x64 sprite of a boss:
ObjSprite2D_SetDestRect(obj,0,0+hover,64,64+hover);
Then mutate the hover var as you please with sin() or something to make it smooth up/down.
Library: sounds.txt
let SFX_TAN00 = loadSFX("pathname/tan00.wav");
let SFX_LAZER00 = loadSFX("pathname/lazer00.wav");
let SFX_KIRA00 = loadSFX("pathname/kira00.wav");
function loadSFX(path) {
let obj = .....;
ObjSound_Load(path);
Sound stuff;
return obj;
}
let Area = GetShotIdInCircleA2(ObjMove_GetX(obj),ObjMove_GetY(obj),100,TARGET_ENEMY);
while(!Obj_IsDeleted(obj)) {
ObjMove_AddPatternA1(Area,0,0.8,90);
Area = GetShotIdInCircleA2(ObjMove_GetX(obj),ObjMove_GetY(obj),100,TARGET_ENEMY);
yield;
}
let ObjArray; //Create a variable
while(!Obj_IsDeleted(obj))
{
//Store Bullet IDs within the radius into the variable. The variable's type is now considered an array.
ObjArray = GetShotIdInCircleA2(ObjMove_GetX(obj),ObjMove_GetY(obj),100,TARGET_ENEMY);
//Loop through the length of that array with "i"
ascent(i in 0..length(ObjArray))
{
//Apply a change in speed, and angle, after 1 frame for all bullets in the array.
ObjMove_AddPatternA1(ObjArray[i],1,0.8,90);
}
yield;
}
Well it's mostly bullet / laser interactions...
example: When the bullets hit a laser, split bullets in three (a bit like the SCC alice spell)
But really, it's just to see how to do arrays, all i can do with them are just simple things like set shot graphics, positioning, and such... I don't really know much about bullet arrays.
Well, you can iterate through an array and call commands on each of the items inside. You would probably use obj-obj collision for bullets hitting a laser - I did this and the amount of lag due to accessing arrays was phenomenal.
On a sidenote, Sparen has asked mkm to make array accesses constant-time.
Curious, by what means have you concluded array access isn't constant? Because from my own testing, it very much is. I think it's very likely you're seeing non-constant times from something else.
Hi! I was wondering, how sometime (if it's not very often), replays are completly broken and the player starts to do anything (but certainly not what I do in the run) after a random time? Even juste after I record the replay.
It's not the first time I notice that but I have no idea why it happen and why. And how to avoid this? It's really problematic for full games or serious scripts.
let angle = 0;
let r = 100;
let r2 = 0;
loop(10){
loop(40){
let id = CreateShotA1(GetEnemyX(objBoss) + r*cos(angle), GetEnemyY(objBoss) + r2*sin(angle), 1, angle, 11, 10);
angle += 360/40;
}
r -= 10;
r2 += 10;
wait(2);
}
It's me again ! :ohdear: I would like to have some help with some maths...Code: [Select]let angle = 0;
let r = 100;
let r2 = 0;
loop(10){
loop(40){
let id = CreateShotA1(GetEnemyX(objBoss) + r*cos(angle), GetEnemyY(objBoss) + r2*sin(angle), 1, angle, 11, 10);
angle += 360/40;
}
r -= 10;
r2 += 10;
wait(2);
}
In this pattern, the bullets spawn from a variable radius, ant it forms a horizontal oval who goes into a vertical one. However the problem is : I want this oval to move depending of the player, so the bullet are aimed at the player. But this oval transformation seems "fixed" and the bullets goes in a weird angle when aimed. How to make this oval rotate at the angle to the player please ?
function GetEllipticX(let bX, let xLength, let yLength, let gapAngle, let dispAngle){
return bX+xLength*cos(gapAngle)*cos(dispAngle)-yLength*sin(gapAngle)*sin(dispAngle);
}
function GetEllipticY(let bY, let xLength, let yLength, let gapAngle, let dispAngle){
return bY+xLength*cos(gapAngle)*sin(dispAngle)+yLength*sin(gapAngle)*cos(dispAngle);
}
let angle = 0; // Since we're offsetting the angle of the ellipse, the position of the first bullet should stay at 0 degrees to ensure it aims at the player.
let angle2 = GetAngleToPlayer(objBoss); // The angular alignment of the ellipse, aimed at the player.
let r = 100;
let r2 = 0;
loop(10){
loop(40){
let sX = GetEllipticX(GetBossX,r,r2,angle,angle2-90); // Utilizing the GetEllipticX function.
// As the ellipse is supposed to begin in a horizontal position, we subtract 90 from angle2.
let sY = GetEllipticY(GetBossY,r,r2,angle,angle2-90); // The GetEllipticY variant of the above.
let trueAngle = angle+(angle2-90); // Still, using the above offsets the actual angle of the bullet due to the rotation.
// We fix this by adding "angle2-90" back to the original angle.
let id = CreateShotA1(sX, sY, 1, trueAngle, 11, 10);
angle += 360/40;
}
r -= 10;
r2 += 10;
wait(2);
}
You will need to use rotation matrices
I hope that helps~
task initStage {
InitializeStageScene;
if(replay) { SetStageReplayFile() SetStageIndex(<index get from replay> }
else { Playerscript(ry... SetStageIndex(1); }
Kick off STG script...
}
// if stage cleared
task clearStage {
if(stage != 3) { jump stage (index + 1) initStage; }
else { FinalizeStageScene, clear game menu, save replay etc }
}
So over the last 2 hours I have been lit. tearing my hair out with the ANSI - UTF-8 and SHIFT-JIS encoding/conversion.
Within Notepad++ I was happy adding spellcard names in both English and Japanese.
- My Japanese characters turn gibbrish kanji/symbols. Even if I see them in notepad correctly displayed, if I set Character Set to Shift-JIS, they turn to gibbrish.
- Saving file / reloading countless times keeps this problem up
- UFT-8 without BOM is being set each and every time
- Even worse, if I rewrite the kana/kanji manually , save and reload the file it jumps to ANSI even.
And even more worse. This occurred to half the spell cards. Most of them I fixed by reloading/resaving/reencoding etc. But these last few keep on being persistent and ***** annoying.
Am I doing something wrong in regarding to setting to Japanese characters Shift-Jis? Why is it constantly jumping to ANSI?
let x0 = ObjMove_GetX(objEnemy);
while(!Obj_IsDeleted(objEnemy)){
let x = ObjMove_GetX(objEnemy);
if(x - x0 < 0){
// left
}else if(x - x0 > 0){
// right
}else{
// idle
}
x0 = x; // update x-position
yield;
}
alternative(GetEventType())
case(EV_REQUEST_IS_LAST_SPELL){SetScriptResult(true);}
Not a function but an event.
Put this in @Event of your enemy script:Code: [Select]alternative(GetEventType())
case(EV_REQUEST_IS_LAST_SPELL){SetScriptResult(true);}
#UserShotData
shot_image = "./img/enm_eff/bullet00.png
delay_rect = (29,958,65,994)
...
local
{
let current = GetCurrentScriptDirectory();
let customShot = current ~ "bullet_def.txt";
LoadEnemyShotData(customShot);
}
...
#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["ASM - Aragami01"]
#Text["nonspell"]
#include "script/Tutorial/bullet_lib.txt"
#include "script/Tutorial/boss_effects.txt"
#include "script/Tutorial/effect_MagicCircle.txt"
let bossObj;
...
I've currently got a strange issue with Danmakufu which honestly don't know how to handle it anymore :V
It's the following:
I've been working on an own custom shot sheet for a time, everything used to work perfectly, until today when I started Danmakufu, the bullet graphics suddenly didn't show up, the sounds of the bullets firing are still audible though.
The image file doesn't even appear in the 'Texture' section of the log window anymore.
The code is still all the same.
For the bullet definition file (bullet_def.txt):
//...
and then included the defined shot IDs in the CreateShotA1 function. But the graphics don't show up when I execute the script. ???
I really don't know if I did something wrong or it is just a technical error, so if someone here can give some advice would be greatly appreciated. :)
Well, if that's a direct paste of your script, the shot_image doesn't have any ending double-quote.Oh sorry, my bad, there's a closing double quote in my actual script, I didn't directly copy-pasted it here.
First thing's first - is the file path correct? And if so, are you using the shot constants or just the number? (shot constant sheet requires an #include)The file paths were the first thing I've checked when the issue first occurred. Everything is like when it still worked normally about two days ago, the bullets showed up as expected. Until the time when this problem began, I didn't make any change on the code and file paths of the shot image, definition and constants files, except for adding some more bullet definitions. After that, the bullet graphics didn't show up, the path of the texture file also doesn't appear in the log window anymore.
If that doesn't work, is the texture file path correct in the shot sheet?
There is a copyright notice for the Mersenne twister in the license, so that's almost definitely no. Mersenne is much better than C's rand() anyways, which is a pretty crap RNG.
Hi, I have an small question about something in dnh.
I want in a spell of PG to create familiars that have an square made of lasers, that rotate(like Youkai Kori Kassen's final boss last spellcard for both sides, but those are triangles)
I know its using CreateStraightLaserA, but how about the laser movement(along with their angle so it always will be a square)?
Hi, I have an small question about something in dnh.
I want in a spell of PG to create familiars that have an square made of lasers, that rotate(like Youkai Kori Kassen's final boss last spellcard for both sides, but those are triangles)
I know its using CreateStraightLaserA, but how about the laser movement(along with their angle so it always will be a square)?
Drawing this up:
(http://i.imgur.com/RF4ttDU.png)
In general this is how you'd make an n-gon (triangle, pentagon, heptagon, whatever). You have your center point, and each "corner" point is going to be r distance from the center. The angle a will start at an offset of 0, and each next corner point will increase the angle by 360/n. The position of the point is then (r*cos(a), r*sin(a)), plus the x/y of the center. The length of the sides (the lasers, in this case) will be 2*r*sin(180/n) and should be pointed at the angle a+90+180/n. Spinning the whole n-gon around is just a matter of increasing the angle offset per frame and recalculating the positions and directions. Additionally you can replace the lasers with bullets with just a little extra work.
I can write down some code if you find this too difficult to implement.
well, I mean,Simplified Chinese shows ????? in this game text.
our programmer solved this problem by adding an empty line in lib_boss.dnh and lib_enemylibs.dnh
[attach=1]
[attach=2]
line numbers of ?#include? goes wrong when changing to UTF-16.
eg.[attach=3]
[attach=4]
it should read "zakodraw", but it reads"/zakolib/zakolib/..."
edit:it causes more strange bugs, sad
2015/04/29 02:58:05.581 DirectSound:音声データ解放[C:/Users/Kook/Desktop/TISTUFF/.touhou/th_dnh_ph3_1pre6/th_dnh_ph3/script/CYws/cy5/se/cut00.wav]
2015/04/29 02:58:05.583 DirectSound:音声データ解放[C:/Users/Kook/Desktop/TISTUFF/.touhou/th_dnh_ph3_1pre6/th_dnh_ph3/script/CYws/cy5/se/eco01.wav]
2015/04/29 02:58:05.585 DirectSound:音声データ解放[C:/Users/Kook/Desktop/TISTUFF/.touhou/th_dnh_ph3_1pre6/th_dnh_ph3/script/CYws/cy5/se/freeze07.wav]
2015/04/29 02:58:05.588 DirectSound:音声データ解放[C:/Users/Kook/Desktop/TISTUFF/.touhou/th_dnh_ph3_1pre6/th_dnh_ph3/script/CYws/cy5/se/loop001.wav]
2015/04/29 02:58:05.589 DirectSound:音声データ解放[C:/Users/Kook/Desktop/TISTUFF/.touhou/th_dnh_ph3_1pre6/th_dnh_ph3/script/CYws/cy5/se/on01.wav]
2015/04/29 02:58:05.590 DirectSound:音声データ解放[C:/Users/Kook/Desktop/TISTUFF/.touhou/th_dnh_ph3_1pre6/th_dnh_ph3/script/CYws/cy5/se/paper00.wav]
2015/04/29 02:58:05.592 DirectSound:音声データ解放[C:/Users/Kook/Desktop/TISTUFF/.touhou/th_dnh_ph3_1pre6/th_dnh_ph3/script/CYws/cy5/se/power14.wav]
2015/04/29 02:58:05.594 DirectInput:終了開始
2015/04/29 02:58:05.595 DirectSound:音声データ解放[C:/Users/Kook/Desktop/TISTUFF/.touhou/th_dnh_ph3_1pre6/th_dnh_ph3/script/CYws/cy5/se/sha00.wav]
2015/04/29 02:58:05.596 DirectInput:終了完了
2015/04/29 02:58:05.600 DirectSound:終了開始
2015/04/29 02:58:05.600 DirectSound:音声データ解放[C:/Users/Kook/Desktop/TISTUFF/.touhou/th_dnh_ph3_1pre6/th_dnh_ph3/script/CYws/cy5/system/se/seUseSpellCard.wav]
2015/04/29 02:58:05.712 DirectSound:終了完了
2015/04/29 02:58:05.717 ShaderManager:Shaderを解放しました(Shader Released)[ float4 lightDirection;
float4 materialAmbient : MATERIALA]
2015/04/29 02:58:05.719 TextureManager:テクスチャを解放しました[__RESERVED_RENDER_TARGET__2]
2015/04/29 02:58:05.720 TextureManager:テクスチャを解放しました[__RESERVED_RENDER_TARGET__1]
2015/04/29 02:58:05.721 TextureManager:テクスチャを解放しました[__RESERVED_RENDER_TARGET__0]
2015/04/29 02:58:05.722 TextureManager:テクスチャを解放しました[__RENDERTARGET_TRANSITION__]
2015/04/29 02:58:05.724 DirectGraphics:終了開始
2015/04/29 02:58:05.725 DirectGraphics:終了完了
2015/04/29 02:58:05.727 アプリケーション終了処理完了
#TouhouDanmakufu[Single]
#ScriptVersion[3]
#Title["St1 Sp3"]
#Text["Third spell!"]
#Player["./../../player/player0.dnh"]
#System["./../../system/system.dnh"]
#include "./../../prologue.dnh"
#include "./../../player/shotc.dnh"
let id = 28;
let level = 7;
#include "./../spell_header.dnh"
#include "./render_boss.dnh"
@Event {
alternative (GetEventType)
case (EV_REQUEST_LIFE) {
SetScriptResult(6000);
}
case (EV_REQUEST_TIMER) {
SetScriptResult(72);
}
case (EV_REQUEST_IS_DURABLE_SPELL) {
SetScriptResult(true);
}
case (EV_REQUEST_SPELL_SCORE) {
SetScriptResult(spellBonus);
}
}
@Finalize {}
task TWork {
let height = GetStgFrameHeight;
let width = GetStgFrameWidth;
ObjEnemy_SetDamageRate(objBoss, 0, 0);
let d = getDifficulty;
let speed = 1 + 0.1 * d;
let count = truncate(1 + 0.34 * d);
let period = 240 / (1 + 0.15 * d);
let ways = 16 + 4 * d;
ascent (i in 0 .. 21) {
loop (count) {
let s = createCircleShot(width / 2, height / 2, 15 * i, period / rand(-1, 1), rand(0, 360),
DS_BALL_M_A_RED + truncate(rand(0, 8)), 120, 99999);
ObjShot_SetSpellResist(s, true);
ObjShot_SetAutoDelete(s, false);
}
}
task amulet(s, g) {
ObjMove_SetAngularVelocity(s, m * g);
wait(30);
ObjMove_SetAngularVelocity(s, 0);
}
let m = 1;
while (!isDead) {
let g = randomSign;
let a = GetAngleToPlayer(objBoss - 30 * m * g);
loop (ways) {
let s = CreateShotOA1(objBoss, 2.9, a, DS_BILL_RED, 0);
amulet(s, g);
a += 360 / ways;
}
m += 0.05;
wait(period / 3);
}
ObjEnemy_SetDamageRate(objBoss, 100, 100);
}
I have a question regarding BGM and sounds.
?dit2: I figured out that not deleting the sound object (SFX) fixes the problem. But I don't want to not-unload them, because I don't want it to affect the framerate.
Can you help me?
Edit: didn't wanted to post it that early ._. Keyboard WHYY??
Hi!When a player dies or has no more remaining lives, GetStageSceneResult is mutated but also GetPlayerState is mutated. Debug text output those result and see what happens. What you need to do is prevent your stage script from closing. I have no continue mechanics but the pause method pretty much works the same way is my guess. A player who runs out of lives does nothing. Just like boss scripts, you need to define what happens when the game "ends".
I try to implement a Continue system. I try to do this in the EndScene script. When the player has no remaining lives, the EndScene start and all work well but the stage script end and I can't return to it at the exact point where it stopped. I search in the function list on the wiki but i found nothing useful that can help me.
I also try to use a pause-like script but I can't pause the entire game while the pause-like script is runningThis makes no sense. If you call the pause functions, everything in the stage script will stop running. PauseStageScene(bool); will enforce this.
Hey Helepolis :)Try the following.
Here's the paste http://pastebin.com/BVGU0Mxc
It's not Everything but I think the most important stuff :P
The script was running on pre3, but i tried it with pre6a too and the error stayed the same.
I also uploaded the entire script folder to MediaFire: http://www.mediafire.com/download/dyw2go5ce1ohhe1/ShattSky.zip
task TCloseScript {
while(GetPlayerState() != STATE_END) {yield;}
loop(140){yield;}
if(GetScore >= GetAreaCommonData(CDAN, "HiScore",1000000)) {SetAreaCommonData(CDAN, "HiScore", GetScore);}
SaveCommonDataAreaA1(CDAN);
loop(10){yield;}
if(GetCommonData("CONTINUES",-1) < 0) {
CloseStgScene();
} else {
}
}
When the player is out of lives, the script don't end and continue to run. But I have still no idea how to manually call a PauseScene in this else: if(GetCommonData("CONTINUES",-1) < 0) {
CloseStgScene();
} else {
}
I call a script with StartScript(LoadScriptInThread(path));
but the stage don't stop running like in a Pause Script.Helepolis> Thanks. I do that (in fact it's done since a long time but I call another CloseStgScene in an include of the script)I don't think you should call anything manual. My core script isn't a package either. It is a normal loaded script. Stage script is basically Stg. I have 2 listeners in my game: One runs inside the core script (for pause / stageresult) and one runs inside the stage script.Code: [Select]task TCloseScript {
When the player is out of lives, the script don't end and continue to run. But I have still no idea how to manually call a PauseScene in this else:
while(GetPlayerState() != STATE_END) {yield;}
loop(140){yield;}
if(GetScore >= GetAreaCommonData(CDAN, "HiScore",1000000)) {SetAreaCommonData(CDAN, "HiScore", GetScore);}
SaveCommonDataAreaA1(CDAN);
loop(10){yield;}
if(GetCommonData("CONTINUES",-1) < 0) {
CloseStgScene();
} else {
}
}Code: [Select]if(GetCommonData("CONTINUES",-1) < 0) {
I call a script with
CloseStgScene();
} else {
}Code: [Select]StartScript(LoadScriptInThread(path));
but the stage don't stop running like in a Pause Script.
Oh and I do that out of a Package Script for the moment.
Inside [ Core script or w/e.txt ]
{
Initialize stage(ry;
StateListener;
}
task StateListener {
// Pause menu
if(pressed ESC) { pausemenu; }
if(playerstate == DED && hascontinues > 0) {
launch special continue pause menu;
}
// To handle when a stage is cleared/player ded/stage disrupted
if(stageSceneState == STAGE_STATE_FINISHED) { }
}
Try the following.
- Don't create global var for your music object like that (let musicobj = sound_create) etc.
- Change task PlayMusic into function prepareMusic(path) (remove the other parameters)
- Move the global let objBGM into your function.
- Remove the ObjSound_Play function.
- Add as final line in the function return objBGM;
Now create your sound obj by typing for example: let music01 = prepareMusic(pathname); And then use ObjSound_Play(music01) to play the music obj or w/e you want to do with it.
Important:
- Music files have to be OGG for lesser problems. Convert them to OGG if they aren't.
- Don't use ObjSound_SetLoopTime but use ObjSound_SetLoopSampleCount and work with samples to define the loop region. More accurate and works better.
Try that first.
if(pressed ESC) { pausemenu; }
How I can do that? for the pressed ESC I know but for the pausemenu;... ?(https://www.shrinemaiden.org/forum/index.php?action=dlattach;topic=16584.0;attach=39337;image)I see how you do but it don't work for me.
StartScript(stg1ID);
while(!IsCloseScript(stg1ID)) {yield;}
loop(10){yield;}
StartScript(stg2ID);
while(!IsCloseScript(stg2ID)) {yield;}
etc.
VStartScript
and to end them I use CloseScript(GetOwnScriptID);
. Is there a good tutorial to learn how to make custom Item scripts out there?
#UserItemData
item_image = "./img/Item.png"
ItemData{
id = 1 //StrabiBonus
//type = POINTS
rect = (0, 0, 19, 19)
render = ALPHA
out = (0, 23, 19, 37)
}
StartItemScript(GetCurrentScriptDirectory~"./../Item.dnh");
LoadItemData(GetCurrentScriptDirectory~"./../item_shotsheet.dnh");
The first line sets the given item script to your item script, and the second one loads the item shot sheet.if (canDeleteEnemy(enemy)) {Obj_Delete(enemy); return;}
Is it possible to save a screenshot as a .png, instead of always being stuck with .bmp?Afaik you can't. 0.12m did also defaults also bmp files.
Is it possible to spawn enemy shots in a player script? For some reason CreateShotA1 won't work in a player script... is it designed that way or am I doing something wrong?It depends what you mean by enemy shots. Can you use CreateShotA1() and so on? Yes, but the bullets won't show up unless the shot data is loaded with LoadPlayerShotData(), as usual. LoadEnemyShotData() won't do anything useful (it will load the shot data somewhere, but is moot). However, any bullets fired like this are still player bullets, and won't hit you. If you use GetShotCount(TARGET_PLAYER), they will count.
Why specifically enemy bullets?
I'm not really *curious* about the motivation; if they explain what they want to do from the beginning then you can recommend an alternative, rather than looking only at one particular way to do things.
makeDummyHitbox(objPlayer, 1);
task makeDummyHitbox(parent, radius){
while(!Obj_IsDeleted(parent)){
let e = ObjEnemy_Create(OBJ_ENEMY);
while(!ObjCol_IsIntersected(e)){
ObjEnemy_SetIntersectionCircleToShot(e, ObjMove_GetX(parent), ObjMove_GetY(parent), radius);
yield;
}
doSomething();
Obj_Delete(e);
}
}
If you're looking for a way for players to trigger a hit on players, you can do so by creating a dummy enemy and checking for intersections.Code: [Select]makeDummyHitbox(objPlayer, 1);
task makeDummyHitbox(parent, radius){
while(!Obj_IsDeleted(parent)){
let e = ObjEnemy_Create(OBJ_ENEMY);
while(!ObjCol_IsIntersected(e)){
ObjEnemy_SetIntersectionCircleToShot(e, ObjMove_GetX(parent), ObjMove_GetY(parent), radius);
yield;
}
doSomething();
Obj_Delete(e);
}
}
You can then use user events or something to handle "player hit" behaviour. However, your own bullets will hit this enemy, so just make sure they don't, I guess.
I realize a more rigorous way of setting this up might be to mark your own shots. You can do this with something like Obj_SetValue(shot, "PlayerSource", GetOwnScriptID()), and then checking only those shots for collision, or something. The downside with this approach is that you'd have to make sure to set the object values to all player shots like this.
@MainLoop
{
let playerX = ObjMove_GetX(player)
let playerY = ObjMove_GetY(player)
CreateShotA1(playerX, playerY, 2, [don't know what to do with angle], [bullet graphic here], 5)
}
Am I right to say that the third value (the 2) is in frames/second, and the last value is in frames?
Is this a valid MainLoop? The effect I want here is the enemy to shoot a stream of any bullet at a certain speed at the player's hitbox:Code: [Select]@MainLoop
Am I right to say that the third value (the 2) is in frames/second, and the last value is in frames?
{
let playerX = ObjMove_GetX(player)
let playerY = ObjMove_GetY(player)
CreateShotA1(playerX, playerY, 2, [don't know what to do with angle], [bullet graphic here], 5)
}
Is this a valid MainLoop? The effect I want here is the enemy to shoot a stream of any bullet at a certain speed at the player's hitbox:Code: [Select]@MainLoop
Am I right to say that the third value (the 2) is in frames/second, and the last value is in frames?
{
let playerX = ObjMove_GetX(player)
let playerY = ObjMove_GetY(player)
CreateShotA1(playerX, playerY, 2, [don't know what to do with angle], [bullet graphic here], 5)
}
I'm currently following Sparen's ph3 tutorial.
I don't really know what I'm doing wrong, but every time I run the script, Danmakufu hangs.
Here's (http://pastebin.com/VXqT33Nj) my script.
I don't really know what to do now...
task MainTask {
movement;
while(ObjEnemy_GetInfo(objBoss, INFO_LIFE)>0){
let angleT = GetAngleToPlayer(objBoss);
loop(13){
ascent(i in 0..3){
CreateShotA1(ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 2.5-i/3, angleT, DS_FIRE_RED+1, 5);
}
angleT+=360/13;
}
yield; // <--------
}
}
Correct me if I'm wrong, but I would think never. If GetShotIdInCircleA2 detects one bullet, it'll return its ID as a one-element array. If there are no bullets, it'll simply return an empty array.
[] == [1] #=> error
[] == ["a"] #=> error
[] == ['a'] #=> false
[] == "" #=> true
erase([1], 0) #=> []
erase([1], 0) == erase([2], 0) #=> true
erase([1], 0) == erase([true], 0) #=> error
[1, 2, 3][0..0] #=> []
[1, 2, 3][0..0] == [4][0..0] #=> true
[1, 2, 3][0..0] == [true][0..0] #=> error
The yaw-pitch-roll system is rotating an object (in this case the camera) about its own y-x-z axes. When the object is upright, the y-axis points up and down, the x-axis points to your left and right, and the z-axis points at and away from you.
The best way I find to visualize the camera's viewing angle is with an analogue to your monitor:
- Spinning your monitor around its base is change in yaw (rotation about y-axis)
- Tilting your monitor's viewing angle up and down is change in pitch (rotation about x-axis)
- Flipping your monitor 90 degrees to vertical orientation is change in roll (rotation about z-axis)
The direction your monitor points here is camera's perspective. Changing the yaw, pitch and roll change where the camera points, from a fixed position.
But the camera doesn't have to be fixed. If you change where the camera is positioned in 3D space but fix the viewing angle, clearly it will point at something else. The camera's focal point is the position in 3D space where the camera bases its own position on.
Imagine a sphere (or a dome) defined around the focal point. The camera lives on that sphere, and you can then think of the focal point as a center point at "ground level".
The radius of the sphere is the distance from the camera to the focal point.
The elevation angle is the angle from the ground, moving into the sky (or negative, moving beneath the ground). Put another way, increasing the elevation angle is like fixing the x-position of the camera and moving it along the sphere, starting by intersecting the z-axis at 0 and eventually intersecting the y-axis at 90.
The azimuth angle is the angle circling around the focal point from a fixed elevation. If the elevation is 0, for example, changing the azimuth is like circling around the focal point at ground level. If the elevation is 90, changing the azimuth keeps you in the same place. In terms of the axes, increasing the azimuth angle is like fixing the y-position of the camera and moving it around the sphere, starting by intersecting the z-axis at 0 and eventually intersecting the x-axis at 90.
Important to note is that camera systems will by default always try to aim at the focal point. Whether you increase the elevation or azimuth, the camera will keep aiming at the focal point. Because of this, changing the yaw-pitch-roll is more like changing the camera's offsets in perspective, away from the focal point. Additionally, the camera will try to stay upright relative to the focal point, so if you increase the elevation beyond 90 it'll flip itself over.
Lastly, if you want to move the camera around in its absolute position, without messing with the perspective, just change the focal point's position.
Is it possible to use a video as a texture? For example, could I make a video as the background for a stage? I want to reduce the number of objects in my backgrounds to help reduce slowdown (and thus be able to make more complex backgrounds), so if using a video is even possible would running one cause even more slowdown?
You'd have to render multiple images in sequence, so running one would cause even more slowdown.
I want to reduce the number of objects in my backgrounds to help reduce slowdown (and thus be able to make more complex backgrounds),How many sprites (objects) do you have anyway in your stage? Or do you have large number of meshes?
How many sprites (objects) do you have anyway in your stage? Or do you have large number of meshes?
20 sprites is in my opinion nothing to make the engine lag / cause FPS issues. Why are you using 2D sprites with Vertexes? Triangle strips and fans and such I guess? Why not just rectangles using the 3D sprite?
Edit: Columns in SA Extra or MoF stg6 are quite easy to make in Meta and being 6-sided they won't have much impact on the engine either.
I need help. I would be very pleased to your help.Not quite sure if I understood your questions but:
1) Items used to spawn in (0;0). Is there a way to delete them?
2) What I need to do, that touhou.exe opened a script immediately?
3) How to make glowing effect in 3-D backgrounds? (For example an glowing Lantern). I can use Metasequoia :V
task graphics {
let mirror = ObjPrim_Create(OBJ_PRIMITIVE_2D);
ObjPrim_SetPrimitiveType(mirror, PRIMITIVE_LINESTRIP);
let vc = 64;
let vci = vc + 1;
ObjPrim_SetVertexCount(mirror, vci);
ascent (i in 0 .. vci) {
let t = 360 * i / vc;
ObjPrim_SetVertexPosition(mirror, i, cos(t), sin(t), 0);
ObjPrim_SetVertexColor(mirror, i, 0, 255, 255);
ObjPrim_SetVertexAlpha(mirror, i, 200);
}
Obj_SetRenderPriority(mirror, 0.3);
while (!isDead) {
ObjRender_SetPosition(mirror, sx, sy, 0);
ObjRender_SetScaleXYZ(mirror, sr, sr, 1);
yield;
}
Obj_Delete(mirror);
}
You're using a Line Strip vertex layout, and not a Triangle Fan, which seems to be what you want.
Oh yes of course I know how objects work I just never made dialogs. Yes I checked the wiki but I don't know how to manage the character graphic with the dialog (I just made dialogs with 0.12m version and functions were more precise and easy to use)...that's my main problem.
Do I have to make an object for each sentences?
Okay thank you very much everybody ! I managed to make a dialog and it wasn't easy omgg. I define a valu count = 0 and if count = 1 or 2 etc, display this text... My problem now (I'm so sorry ._.) I don't know how make this kind of thing "if w is pushed, count ++", I tried much things with key functions but it does not work, count stay 0 even if a push the key.
To "solve" the problem i made a loop in mainloop like loop{count++;wait(200);} without key... But it would be better to make a dialog with keys.
(I apologize for my weird english, french dumb here)
function EventWaitA3(frames){//Original Implementation (skips through dialogue quickly) Sparen
while(GetVirtualKeyState(VK_OK) == KEY_FREE){yield;}
wait(frames);
PlaySFX(pshot);
}
if(speed == 0){
if(attack == 0) {
// idle anim
}
if(attack == 1) {
// casting animation
}
}
else if(cos(dir) < 0){}
else if(cos(dir) > 0){}
if(attack == 0) {
if(speed == 0){
// idle anim
}
else if(cos(dir) < 0){}
else if(cos(dir) > 0){}
}
if(attack == 1) {
// casting anim
}
task fireShot {
attack = 1;
// Sound / visual effects or something to show it happening (concentration effect)
wait(15);
attack = 0;
// rest of your attack pattern
}
Hii everyone. Okay I wanna made a trial version of my danmakufu project, I made the 3 first stages with bosses and dialogs etc... Now I want to know if it's possible to configure the application to read directly the main script of my project? I didn't used package script (I don't even know how to use that ...). My main script is a stage script :
http://pastebin.com/7F8NZxMj
Oh okay...but I didn't find any tutorial about package script unfortunately... So can someone help me about that?
Where can PlaySE be called and actually play a sound?
Anywhere, as long as it is given a legitimate path to a legitimate sound file that has been loaded using LoadSound()
I used LoadSound() in the system script and the sound still doesn't play. I'm pretty sure I'm feeding it legitimate paths.
are you using PlaySound()?
Actually, that function doesn't exist. Did you mean PlaySE()?Ah yes, apologies, I actually have touched that since I made my own library for it.
SetCommonData("spellcard",5);
let getcards = GetCommonData("spellcard",0);
??? HELP!Did you set a stage and player script to run using SetStageMainScript() and SetStagePlayerScript()? When running a stage from the default script select menu you can choose your character, but if you're running a package script, you can't do that. You have to tell the package script which player script you want to use for the stage.
I wrote a Package script, and it works normally, ok.
But, when I start playing threw the "th_dnh.def", it starts normally, but can't begin the game, because he cannot find a player.
I have no idea where is the problem.
Did you set a stage and player script to run using SetStageMainScript() and SetStagePlayerScript()? When running a stage from the default script select menu you can choose your character, but if you're running a package script, you can't do that. You have to tell the package script which player script you want to use for the stage.Yes I set both of them. I'm using Package script.
SetCommonData works exactly like in 0.12m. You set a key and a value for it and you can retrieve that value or manipulate it by setting it again.
Example:Code: [Select]SetCommonData("spellcard",5);
let getcards = GetCommonData("spellcard",0);
If you debugtext getcards (or the commondata), you will see that the value should be 5. If for some reason, when GetCommonData is called, cannot retrieve the value, it will return the default value, in this case 0.
Could you please put your package script and .def file in a pastebin?Ok (^_^'), just a moment...
Could you please put your package script and .def file in a pastebin?It quite messy, sorry :0
And when I need to write a text, I should write:Nope. You must write:
if(GetCommonData("language","english"){ text="hello" }
Nope. You must write:
if(GetCommonData("language","english") == "english") { text="hello" }
"language" is the name of the common data.
the first "english" is the default value of the common data
the second "english" is what you check with the if.
CommonData are used to store numbers, texts, arrays, variables values, etc. and share them between differents scripts/task/fuction (or in the same script.task/function) with GetCommonData and SetCommonData.
The arguments of SetCommonData are the name of the CommonData and the value of the CommonData.
The arguments of GetCommonData are the name of the CommonData and the default value returned if the CommonData has no value.
Is it clearer now?
Ok, that's a slightly nonobvious problem (assuming this is actually the problem). When using SetStagePlayerScript(), the only valid player scripts that you can use are the ones you list in the package script's #Player header. If you don't have a #Player header, it defaults to #Player[ALL], which contains only the player scripts under the script/player folder. Since your player scripts aren't there, it will tell you none are available.
Add a #Player["./Reimu/Reimu.txt"] to the package script and try that.
If that doesn't work, can you:
1) List what player scripts you have in the script/player folder
2) Explain what happens when you launch th_dnh main menu (without a .def) -> select Package -> start your script and keep going until it errors
Hello. I've been having some problems with Danmakufu now.- You're not closing the the script in your finalize, just summoning an explosion after the boss HP reaches 0.
I'm almost finishing my script [with 4 difficulties and 2 extra spells in Single], but, for some reason:
1. The script does not automatically end on the 4 difficulties.
2. The extra spells are crashing Danmakufu when Remilia's HP reaches 0.
The scripts are here: http://pastebin.com/jMhSCDbj and http://pastebin.com/0YaTEhFv
- You're not closing the the script in your finalize, just summoning an explosion after the boss HP reaches 0.
- Take a closer look at your MainTask. How does the MainTask "walkthrough" the code if you were to say out loud what is all happening there. What do you think what happens when the HP is 0 or lower?
- Changed the Finalize to others Singles' Finalize, but the Plural still didn't finish.I am confused, plural? Do these cards end when you play them separately but not in plural? I think you're missing the point about closing scripts. In both your posted pastebin links, I cannot track the function to close scripts.
I am confused, plural? Do these cards end when you play them separately but not in plural? I think you're missing the point about closing scripts. In both your posted pastebin links, I cannot track the function to close scripts.
task fire01 {
let x = 0;
let dir = 0;
loop {
while(x<5) {
loop(36) {
CreateShotA1(obj_boss_x,obj_boss_y,3,dir,15,15);
dir+=360/36;
}
wait(5);
x++;
}
wait(60);
let x = 0;
let dir = 0;
}
}
task mainTask {
bossAnim;
backgroundDraw;
movement;
scriptEnd;
}
task backgroundDraw {
let bg = ObjPrim_Create(OBJ_SPRITE_2D);
Obj_SetRenderPriorityI(bg,21);
ObjPrim_SetTexture(bg,bg_eerie);
ObjSprite2D_SetSourceRect(bg_eerie,0,0,386,450);
ObjSprite2D_SetDestRect(bg_eerie,0,0,GetStgFrameWidth,GetStgFrameHeight);
}
Umm, I'm currently 'animating' my script's enemy, but I have no idea of how to check the angle my enemy face. Can anyone help with this?
I've been having this issue where when the boss dies bullets will be fired from the top left corner for a while. If I remember right this is due to the script not despawning the boss correctly, but I don't remember how to fix it because I can't find the tutorial that mentioned it.
Every time you yield, you must check if the boss is dead before spawning more bullets.That is imo unnecessary method. There is no reason to keep checking for the boss with each yield. And also very shallow explanation too and not helping in discovering why it is going wrong so the user keeps it in mind for future routines/tasks/methods.
task fire {
loop {
CreateShot(ry
yield;
}
}
In 0.12m this would be probably safe to use. In ph3 however you need to make sure things are handled proper. task fire {
loop {
CreateShot(ry
yield;
if(Obj_IsDeleted(obj)) { break; }
}
}
Which isn't wrong but when you have many many other yields / routines / areas you need to check it will become a huge mess. task fire {
while(!Obj_IsDeleted(obj)) {
CreateShot(ry
yield;
}
}
What this does it checks whether the boss is existent (or the obj) before it tries to run the while-loop. The checking is done within the while statement. This gives you a much clean and more defined control on whether to run the loop or not. Keep in mind though you will need to think of possible delays once the loop is executed but for general use, this will do the trick.So simply use this:Code: [Select]task fire {
What this does it checks whether the boss is existent (or the obj) before it tries to run the while-loop. The checking is done within the while statement. This gives you a much clean and more defined control on whether to run the loop or not. Keep in mind though you will need to think of possible delays once the loop is executed but for general use, this will do the trick.
while(!Obj_IsDeleted(obj)) {
CreateShot(ry
yield;
}
}
angular_velocity = velocity / radius
angular_velocity = (velocity / radius) * 180 / pi
Does it really necessitate using all that? I mean yes, it would probably be better to use a lookup table but 64 sines (or whatever) per frame seems a bit much to begin with.
In any case, you'd just make an array and populate it with values, but considering you haven't described how you intend to use it in the first place I can't really expand on that very much...
// slice_offset is incremented every time one slice has been "processed" and reset to 0 after the background drawing has finished
h_offset = (frame_roll + slice_offset) & 31 // frame_roll + slice_offset is AND-ed with %0001 1111 to limit the variable to 32 different values
v_offset = (frame_roll + slice_offset) & 15 // frame_roll + slice_offset is AND-ed with %0000 1111 to limit the variable to 16 different values
// The table with horizontal positions has 32 values and the table with vertical positions has 16 values
2D Version (https://www.youtube.com/watch?v=ekgPo0YfGRI)
3D Version (https://www.youtube.com/watch?v=5JuFV2DoB7s)
t = (t + 360/32) % 360;
h_pos = cx + sin(t) * 50;
v_pos = y + sin(t*2) * 10;
for one slice or something, where y and t increase for each slice.h_offsets = [sin(0*360/32)*50, sin(1*360/32)*50, sin(2*360/32)*50, (29 more...)]; // Or use a loop to populate these lol
v_offsets = [sin(0*360/16)*10, sin(1*360/16)*10, sin(2*360/16)*10, (13 more...)];
// ...
h_pos = cx + h_offsets[(frame_roll + slice_offset) % 32];
v_pos = slice_offset*slice_size + v_offsets[(frame_roll + slice_offset) % 16];
oroffsets = [sin(0*360/32), sin(1*360/32), sin(2*360/32), (29 more...)];
// ...
h_pos = cx + offsets[(frame_roll + slice_offset) % 32] * 50;
v_pos = slice_offset*slice_size + offsets[(frame_roll + slice_offset) * 2 % 32] * 10;
Wait, does PH3 still have the same performance problem with arrays as 0.12m?I'm not sure what you mean by performance problems. I haven't used 0.12m in eons so I don't even know if it has array issues (and I don't really care tbh), but could you elaborate? The main issue with ph3 arrays is that you can't just allocate a given size.
First of all, Danmakufu doesn't have any bitwise operators. Gonna have to work with modulo for that.
Also, I did mean just writing the values out in the script itself if you want.
LookupTable:
.db 0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1
.db 0,-1,-2,-3,-4,-5,-6,-7,-8,-7,-6,-5,-4,-3,-2,-1
:c
I hope the author of Danmakufu adds them in a future update. They are pretty basic (and useful) operations after all.
I have never heard of modulo and I couldn't find anything about how Danmakufu uses them.
What kind of formatting/syntax do I have to use for that?
Another language I work with uses this (and I'm pretty sure Danmakufu doesn't):Code: [Select]LookupTable:
.db 0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1
.db 0,-1,-2,-3,-4,-5,-6,-7,-8,-7,-6,-5,-4,-3,-2,-1
let lookUpTable = [0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -7, -6, -5, -4, -3, -2, -1];
Only concern is that ^ is already used for exponentiation
That would be near-totally pointless, yes.
Bitwise operators are useful for holding a large number of flags.The thing is that any implementation is going to be built using structures and operations that are much more wasteful in space and time, and then those emulated bitwise operations are just going to be used to run some algorithm or make some structure that you already could just have done with the tools already available. It's like an anti-API at that point. You can't say it's space-efficient to use a bit vector to hold flags and perform fast operations on, when your ""bit vector"" isn't space-efficient at all and the operations are just emulated by a bunch of slow stuff anyways.
The thing is that any implementation is going to be built using structures and operations that are much more wasteful in space and time, and then those emulated bitwise operations are just going to be used to run some algorithm or make some structure that you already could just have done with the tools already available. It's like an anti-API at that point. You can't say it's space-efficient to use a bit vector to hold flags and perform fast operations on, when your ""bit vector"" isn't space-efficient at all and the operations are just emulated by a bunch of slow stuff anyways.
task THighScore(){
CreateCommonDataArea("RECORDS"); // Create the Common Data Area
// LoadCommonDataArea returns true if it was loaded properly
let loaded = LoadCommonDataAreaA2("RECORDS", GetCurrentScriptDirectory() ~ "records.dat");
if(!loaded){
SetAreaCommonData("RECORDS", "HIGH_SCORE", 0); // If no high score was loaded, sets the high score to 0
}
loop{
if(GetScore() > GetAreaCommonData("RECORDS", "HIGH_SCORE", 0)){
SetAreaCommonData("RECORDS", "HIGH_SCORE", GetScore());
}
yield;
}
}
// When your script finishes
SaveCommonDataAreaA2("RECORDS", GetCurrentScriptDirectory() ~ "records.dat");
Code: [Select]task THighScore(){
CreateCommonDataArea("RECORDS"); // Create the Common Data Area
// LoadCommonDataArea returns true if it was loaded properly
let loaded = LoadCommonDataAreaA2("RECORDS", GetCurrentScriptDirectory() ~ "records.dat");
if(!loaded){
SetAreaCommonData("RECORDS", "HIGH_SCORE", 0); // If no high score was loaded, sets the high score to 0
}
loop{
if(GetScore() > GetAreaCommonData("RECORDS", "HIGH_SCORE", 0)){
SetAreaCommonData("RECORDS", "HIGH_SCORE", GetScore());
}
yield;
}
}
// When your script finishes
SaveCommonDataAreaA2("RECORDS", GetCurrentScriptDirectory() ~ "records.dat");
task THighScore(){
let pathDigit = GetCurrentScriptDirectory() ~ "img/Default_SystemDigit.png";
let count = 12;
let obj = ObjPrim_Create(OBJ_SPRITE_LIST_2D);
ObjPrim_SetTexture(obj, pathDigit);
ObjRender_SetBlendType(obj, BLEND_ADD_ARGB);
Obj_SetRenderPriority(obj, 0.9);
ObjRender_SetY(obj,100);
CreateCommonDataArea("RECORDS");
let loaded = LoadCommonDataAreaA2("RECORDS",GetCurrentScriptDirectory() ~ "./../../../../records.dat");
if(!loaded){
SetAreaCommonData("RECORDS","HIGH_SCORE",0);}
while(true){
if(GetScore() > GetAreaCommonData("RECORDS","HIGH_SCORE",0)){ //Need here exactly a zero?
SetAreaCommonData("RECORDS","HIGH_SCORE",GetScore());}
let score = GetScore();
score = min(score, 999999999999);
let listNum = DigitToArray(score, count);
ObjSpriteList2D_ClearVertexCount(obj);
ascent(iObj in 0 .. count){
let num = listNum[iObj];
ObjRender_SetX(obj, 495 + iObj * 10);
ObjSpriteList2D_SetSourceRect(obj, num * 36, 0, (num + 1) * 36, 32);
ObjSpriteList2D_SetDestRect(obj, 0, 0, 12, 24);
ObjSpriteList2D_AddVertex(obj);}
yield;}}
...
SaveCommonDataAreaA2("RECORDS",GetCurrentScriptDirectory() ~ "./../../../../records.dat");
loop(200){yield;}
Obj_Delete(music);
CloseStgScene();
...
The dat file is automatically created inside 'data' folder inside your script root when you start saving. But since A2 is being used here it will be saved in target directory.
And I would encourage to use absolute pathing if you're having a directory which is ../../../../ etc. I have no idea what that directory is suppose to be but that is like what, 5th sub folder in root?
No I mean, don't use ./../../../ etc as pathname but use for example script/yourproject/folder1/folder2/records.dat (absolute path).Oh, thanks!
It should appear automatically when your script calls the save commondata area.
Does Danmakufu have a built-in "wait" function that waits for X number of frames?
Does Danmakufu have a built-in "wait" function that waits for X number of frames?
function wait(frames)Huh, that's all it takes? neat
{
loop(frames){yield;}
}
You might not have this depending on how you update dnh, as one of the updates replaces this task for an if statement in the MainLoop. The logic however, is mostly the same.
task TEnd()
{
while(main boss has health){yield;}
Obj_Delete(main boss);
//
SetcommonData("Boss 2 object",boss2);
CloseScript(GetOwnScriptID);
}
Next Single....
@Initialize()
{
boss2 = GetCommonData("Boss 2 object",ID_INVALID); // if this does not exist, then the function will substitute with a different value, in this case, I choose ID_INVALID constant or -1.
}
task TEnd()
{
while(main boss has health){yield;}
Obj_Delete(main boss);
//This time we're saving the boss's position to an array and passing that array.
SetcommonData("Boss 2 Position",[ObjMove_GetX(boss2),ObjMove_GetY(boss2)]);
Obj_Delete(boss2);
CloseScript(GetOwnScriptID);
}
Next Single....
@Initialize()
{
// same as before, if the commondata doesn't exist, use a default value.
let position = GetCommonData("Boss 2 Position",[0,0]);
ObjMove_SetPosition(boss2,position[0],position[1]);
}
Ok, this method works for both sharing and or having an independent lifebar.
You should create a simple enemy object using ObjEnemy_Create(OBJ_ENEMY); assign animations, and stuff and use ObjEnemy_Regist(the id of the enemy); to initialize it.
That is pretty much it, the rest is just transferring from one single to another. Now there are two ways of doing this, one way (what I prefer to do) is to pass the second boss's object id to commondata, and then get that id back in the next single and continue controlling the second boss. Method 2 is similar to method 1 but instead of object id, you pass in the position of the second boss.
Method 1Code: [Select]You might not have this depending on how you update dnh, as one of the updates replaces this task for an if statement in the MainLoop. The logic however, is mostly the same.
task TEnd()
{
while(main boss has health){yield;}
Obj_Delete(main boss);
//
SetcommonData("Boss 2 object",boss2);
CloseScript(GetOwnScriptID);
}
Next Single....
@Initialize()
{
boss2 = GetCommonData("Boss 2 object",ID_INVALID); // if this does not exist, then the function will substitute with a different value, in this case, I choose ID_INVALID constant or -1.
}
Method2Code: [Select]task TEnd()
{
while(main boss has health){yield;}
Obj_Delete(main boss);
//This time we're saving the boss's position to an array and passing that array.
SetcommonData("Boss 2 Position",[ObjMove_GetX(boss2),ObjMove_GetY(boss2)]);
Obj_Delete(boss2);
CloseScript(GetOwnScriptID);
}
Next Single....
@Initialize()
{
// same as before, if the commondata doesn't exist, use a default value.
let position = GetCommonData("Boss 2 Position",[0,0]);
ObjMove_SetPosition(boss2,position[0],position[1]);
}
Any other questions (or something isn't clear), feel free to PM me.
//Variables, constants and inclusions
let objBoss;
let objScene = GetEnemyBossSceneObjectID();
let objPlayer =GetPlayerObjectID();
#include"script/default_system/Default_ShotConst.txt"
#include"script/default_system/Default_Effect.txt"
@Event{
alternative(GetEventType())
case(EV_REQUEST_LIFE){
SetScriptResult(500);
}
case(EV_REQUEST_TIMER){
//SetScriptResult(60);
SetScriptResult(13);
}
case(EV_REQUEST_SPELL_SCORE){
SetScriptResult(1000000);
}
}
@Initialize{
objBoss = ObjEnemy_Create(OBJ_ENEMY_BOSS);
ObjEnemy_Regist(objBoss);
//ObjMove_SetDestAtFrame(objBoss, GetCenterX, 60, 60);
ObjEnemyBossScene_StartSpell(objScene);
TDrawLoop;
TFinalize;
MainTask;
}
@MainLoop{
ObjEnemy_SetIntersectionCircleToShot(objBoss, ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 32);
ObjEnemy_SetIntersectionCircleToPlayer(objBoss, ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 24);
yield;
}
// Tasks ###############
task TDrawLoop {
let imgExRumia = GetCurrentScriptDirectory ~ "ExRumia.png";
ObjPrim_SetTexture(objBoss, imgExRumia);
ObjSprite2D_SetSourceRect(objBoss, 64, 1, 127, 64);
ObjSprite2D_SetDestCenter(objBoss);
}
task MainTask {
ObjMove_SetDestAtFrame(objBoss, GetCenterX, 60, 60)
wait(120);
while(ObjEnemy_GetInfo(objBoss,INFO_LIFE)>0){
CreateShotA1(ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), rand(3,6), rand(0,360), DS_BALL_S_BLUE, 20);
yield;
}
}
}
task TFinalize {
while(ObjEnemy_GetInfo(objBoss,INFO_LIFE)>0){yield;}
if(ObjEnemyBossScene_GetInfo(objScene, INFO_PLAYER_SHOOTDOWN_COUNT)
+ObjEnemyBossScene_GetInfo(objScene, INFO_PLAYER_SPELL_COUNT) == 0){
AddScore(ObjEnemyBossScene_GetInfo(objScene,INFO_SPELL_SCORE));
}
let ex = ObjMove_GetX(objBoss);
let ey = ObjMove_GetY(objBoss);
TExplosionA(ex, ey, 10, 0.6);
Obj_Delete(objBoss);
DeleteShotAll(TYPE_ALL,TYPE_ITEM);
SetAutoDeleteObject(true);
CloseScript(GetOwnScriptID());
return;
}
// Functions ###############
function GetCenterX{
return GetStgFrameWidth/2;
}
function GetCenterY{
return GetStgFrameHeight/2;
}
function wait(n){
loop(n){yield;}
}
function rand_int(min, max){
return round(rand(min, max));
}
Pardon the double posting, but is there a way to make my delay laser follow the player?You can edit your post.
This question can be a bit difficult to be answered because of the complexity of it.
I am working on nanbei Project, it does have a multi-language system (between english and spanish).
the system Works fine, but to make it selectable I need to create a options menu in the package script. the question is. how to do a basic options screen?.
I do know i need CommonDataArea and things, but I need help to make the selectable (yes/no) options and the volume (%) options too. any help?
This question can be a bit difficult to be answered because of the complexity of it.
I am working on nanbei Project, it does have a multi-language system (between english and spanish).
the system Works fine, but to make it selectable I need to create a options menu in the package script. the question is. how to do a basic options screen?.
I do know i need CommonDataArea and things, but I need help to make the selectable (yes/no) options and the volume (%) options too. any help?
Key reading and text objects.
}else if(selectIndex == INDEX_MUSIC) {
selectIndex2++;
if(selectIndex2 > 20) { selectIndex2 = 20; }//Music doesn't wrap to 0
SetAreaCommonData("Config","BGMVolume", 5*selectIndex2);//Index goes up to 20
NotifyEventAll(EV_USER_PACKAGE+82, 0);//Alter music bgm volume
PlaySFX(select);
Okay. I've discovered something about it: The GetStgFrameWidth() returns a 40, like it's supposed to (According to how it's set up), but it looks like the distance the shot reflects is 40 from the frame border instead of the window, which puts it at 80 from the window - double what it's supposed to be. Similarly, reflection off the top is actually offset the same way: double the distance from the top of the window than it should be.The drawing origin depends on the render priority of the object being drawn. If its priority is between 20 and 80 inclusive (more specifically GetStgFrameRenderPriorityMinI() and GetStgFrameRenderPriorityMaxI()) then the origin is at the corner of the play area (STG frame); if it's outside these values the origin is the corner of the window. Using GetStgFrameLeft/Top is mostly for positioning things relative to the frame itself, like the score display. GetStgFrameWidth/Height gets the dimensions of the play area, so you can use it in both contexts.
I have a feeling that means I'm not supposed to be using GetStgFrame(Left/Top/Width/Height) when determining where objects inside (as opposed to on top of) are suppose to be (such as where a shot goes to).
However, it doesn't explain why GetStgFrameWidth gives me 480 when it's set to 520 (aside from the fact that the dissonance is exactly the width of the window's left to the frame's left)
EDIT: Well, that's pretty inconsistent. I'm supposed to be using 0 as opposed to GetStgFrame(Left/Top) for objects in the frame, but using GetStgFrame(Width/Height) gives me the right relative number (the intersection was because of the length of the shot VS the actual position of the shot). Something new everyday :/
The drawing origin depends on the render priority of the object being drawn. If its priority is between 20 and 80 inclusive (more specifically GetStgFrameRenderPriorityMinI() and GetStgFrameRenderPriorityMaxI()) then the origin is at the corner of the play area (STG frame); if it's outside these values the origin is the corner of the window. Using GetStgFrameLeft/Top is mostly for positioning things relative to the frame itself, like the score display. GetStgFrameWidth/Height gets the dimensions of the play area, so you can use it in both contexts.Ahh. This makes perfect sense. I'll certainly have to remember this in the future. Thanks, Drake ^w^
Maybe this questions is not for a ph3? but
Why most of all scripts slow down fps?
Problem with Ph3 Engine?
Or problem with my PC?
It's really annoying?
It is most likely a poor graphics card and/or unoptimized code.
It is most likely a poor graphics card and/or unoptimized code.It was my understanding that the graphics card barely matters for Danmakufu. It's mostly the CPU strength.
Maybe this questions is not for a ph3? but
Why most of all scripts slow down fps?
Problem with Ph3 Engine?
Or problem with my PC?
It's really annoying?
It was my understanding that the graphics card barely matters for Danmakufu. It's mostly the CPU strength.
There's 3 possibilities:
1. There's either too many curvy lasers;
2. Bomb-resistant bullets might lag upon using bombs onto them; (Take Lefkada's Youmu's bomb as an example. I experienced heavy lag upon using the bomb on a completely bomb-resistant spell)
3. Too many bullets onscreen, like 2000 bullets or so. That is either an issue with your PC or an issue with Danmakufu.
Maybe this questions is not for a ph3? but
Why most of all scripts slow down fps?
Problem with Ph3 Engine?
Or problem with my PC?
It's really annoying?
Danmakufu isn't exactly the most performance pretty engine. In fact, it is pretty poor with performance ratings. Lag comes from an excessive amount of something. In dnh this can be having too many bullets (1000+), too many sprites, tasks, etc... Also keep in mind that dnh is not a multi-threaded engine, and collision, drawing logic, etc... is handled on a single thread.
With that being said, your computer's overall performance does play a part in this. Can it do all of the calculations needed within 16 milliseconds? The answer is reflected by what the average fps says. Mkm, traded performance for flexibility but didn't add anything to help the performance side. The best thing you can do is use your own engine or an alternative, whatever that may be.
If scripts were running at 60 before and now they're running slower, check to see if your computer's power options are set to use a power plan that cuts performance to save power. I remember I had a laptop with a "balanced" power plan set and it crippled performance badly with DNH.
Hi ! I want to ask something : If we have 5 tasks (Attack1, Attack2, Attack3, Attack4, Attack5), how do I call one of these tasks randomly ?Note sure if best method but:
As if the script can begin either with Attack2 or even Attack5, but with random ?
Note sure if best method but:
I tested whether I can add tasks inside an array but Danmakufu doesn't likes that so that is out of the question I think.
Possible solution: Somewhere when your script kicks off or when you want to make the randomized attack --> Create a loop and use the function rand (don't forget to round it to get a int) to randomize a variable (integer) and then perform statements. Example: If randAttack == 0 >> Attack1 if randAttack == 1 >> etc. Decide the delay (yield / wait) in which the rand function needs to pick a new number in the loop.
Perhaps not the most award winning method but works.
Is there any reason (performance or otherwise) not to use a mesh for the entire background?
Quoting myself in case people didn't see my question.Not sure what you're trying to ask here. Mesh for the entire background? Any specific reason why you would prefer one single mesh for entire background? I remember someone had inserted a detailed Pagoda mesh as test and there was no FPS drop or something. Though I cannot remember the youtube video.
Not sure what you're trying to ask here. Mesh for the entire background? Any specific reason why you would prefer one single mesh for entire background? I remember someone had inserted a detailed Pagoda mesh as test and there was no FPS drop or something. Though I cannot remember the youtube video.
I have a complex request, I'm currently hustling a fangame demo for use in my thesis. Are there any tutorials for:
- Character dialogue
- Spell Card declarations (namely the visual and sound effects)
- Automatically running a script on startup that bypasses Danmakufu's default menu, much like Helepolis' game.
//--------------------------------------------------------------
package.script.main = script/Digital Earth Conquest/DEC_Package_Main.dnh
//--------------------------------------------------------------
window.title = DIGITAL EARTH: CONQUEST
I see, thank you for the response.Unfortunately there is no such tutorial :ohdear:. You'll have to design it all yourself, including difficulty select screen, stage select screens or any form of Menu system.
EDIT: I knew I forgot something! Is there a tutorial on character select screens?
One long trip at the IRC later...
Situation: A single script causes program crash
Plan: Identify What in these single scripts are messing up their inclusion in plural scripts.
Relevant Code: Plural Script File (http://pastebin.com/PGLMNDrN), Single Script File (http://pastebin.com/hgx9ZbDL) (with minor revisions)
let objScene = GetEnemyBossSceneObjectID();
#include"script/default_system/Default_ShotConst.txt"
#include"script/default_system/Default_Effect.txt"
#TouhouDanmakufu[Plural]
#ScriptVersion[3]
#Title["Sandbox File 08"]
#Text["Tutorial Thing - Plural Scripts"]
// Note: Default game field is 384 x 448
//Variables, constants and inclusions
// Empty
@Event{
}
@Initialize{
TPlural;
}
@MainLoop{
yield;
}
// Tasks ###################
task TPlural{
let dir=GetCurrentScriptDirectory();
let obj=ObjEnemyBossScene_Create();
ObjEnemyBossScene_Add(obj,0,dir~"SandboxFile2.txt");
ObjEnemyBossScene_LoadInThread(obj);
ObjEnemyBossScene_Regist(obj);
while(!Obj_IsDeleted(obj)){
yield;
}
CloseScript(GetOwnScriptID());
}
- Force layers by using Obj bullets and use the layer function to set the desired layers. In ph3, we can now work with double digits for layers instead of single digit. So gives more flexibility.
Do you mean tasks and "let obj=createshot..."? I already know how those work but I can't find anything related to layers in the tutorials or wiki. And the tutorials about object bullets are for 0.12 (and don't mention layers either).
http://pastebin.com/M3dnaGwC
I'm having problems with my package script, for a reason I probably fail to understand. When I reach running the Stage script through it, it gives me an error saying "LoadEnemyShotData is not defined" (or some other function that should be default). However it works when I try to run the Stage.txt itself so it's nothing inside there, and I've been told that I have to define the basic functions on the package. My question is: How? I've tried using #Include but that's obviously wrong.
This is my last hurdle, after which I can start piling everything together.
Layers are as follows. Please note that this only applies for Render Priorities between 0.2 and 0.8.
Let's say you have a bullet rendered with the default render priority (50?). Now, if we were to do the following:
let obj = CreateShotA1(192, 224, 0, 0, 0, 0);
Obj_SetRenderPriority(obj, 0.51);
Then this new object would render above all other shot objects on the screen due to its render priority being higher than those of the other shots. In fact, it will render above all things with a render priority below 0.51. If multiple objects are spawned with the same render priority, the ones created later will render over the ones created earlier.
(I hope this is the right place to ask this question ><)
I (might) want to make a Double Spoiler-style danmakufu game so I am trying to re-create the shooting mechanics. I found this author (E.Over0.01) who already made the engine (website: http://anythingfantasy.blog104.fc2.com/blog-entry-137.html ) although it is not compatible with the latest version of ph3. The last seen activity from the author is at Feb 2014 so do I still try to seek permission from him to use the systems? Or is it alright to help translate the codes without permission, but still giving him the credit?
In Package Mode, which you are in, you cannot simply load a plural script and play it - the system is very different. You must start a Stage and inside the stage, load your plural.Thank you for the reply,
To make a Stage Scene, you must
InitializeStageScene();//Loads stage path
SetStageIndex(indexStage); //where index Stage is the stage number
SetStageMainScript(pathMainScript); //stage path
SetStagePlayerScript(pathPlayer);//replays ignore this
StartStageScene();
After this, you use TerminateStageScene(); to terminate the stage scene (if you want to) and use STAGE_STATE_FINISHED as your control statement.
See http://dmf.shrinemaiden.org/wiki/Package_Functions for more information
Thank you for the reply,although when I tried the code as-is, the stage automatically stops upon playing.Nope, I just don't know how to stave-off ClosePackage().
All I got so far is while(stageSceneState!=STAGE_STATE_FINISHED){yield;} but that doesn't work.
while(GetStageSceneState()!=STAGE_STATE_FINISHED){yield;}
ClosePackage;
break;
AttackName("SUPER ULTRA MEGA GIGA DEATH VORTEX OF ULTIMATE DOOM EX ++ MARK II ENHANCED FROM HELL AND STUFF OMG I AM RUNNING OUT OF THINGS TO SAY RIGHT NOW BUT IT'S OKAY YOU'RE GONNA DIE BY THE TIME YOU'RE DONE READING THIS ","RED");
"This is a very long piece of text [r] but this part will be put on the next line"
UseCode: [Select][r]
to next line. Otherwise, ph3 will auto next line depending on the width you forced using the text object functions. But that cuts off by the character. So better to manually use the commands.
Huh? Is that so? How come though? Isn't there a specific font set by default? And there is also default width and spacing between characters. You can even manipulate these with the text object commands.
Curious. Which OS difference btw?
Edit
Tbh, by default you don't want to rely on the max width and let ph3 cut it for you. It cuts characters and not words.
On Mac, fonts are rendered with less width than on Windows, etc. So like, I had an issue where the last letter of some words was dumped onto a new line. It was annoying.Oh, that is good to know. In that case it would be safer to use [r] with plenty of space left compared to actual width of the object.
Hi. Is there a tutorial or something to leark how to make custom players? I search in the wiki but can't find anything for ph3, the same with the videtutorials, I only found Helepolis' but they are for 0.12.
Thanks.
if(ObjMove_GetX(id) <= GetPlayerX+50 && ObjMove_GetX(id) >= GetPlayerX-50 && ObjMove_GetY(id)<=GetPlayerY+50 && ObjMove_GetY(id)>=GetPlayerY-50){
//stuff happens;
}
Hi again, wanted to ask, how do I make an object collision circle radius ? All I can do for now is a square radius :Code: [Select]if(ObjMove_GetX(id) <= GetPlayerX+50 && ObjMove_GetX(id) >= GetPlayerX-50 && ObjMove_GetY(id)<=GetPlayerY+50 && ObjMove_GetY(id)>=GetPlayerY-50){
//stuff happens;
}
Is it possible to make this radius circular ?
Hum, can you make an example as a code please ? Because I don't really understand how to use that formula in a code :ohdear:
I'm not talking about bullets' hitboxes or anything, just a radius zone where thing happens if a bullet is inside (named "id").
[attach=1] [attach=2]
(Excuse the poorly made pictures :V)
if (GetObjectDistance(player, bullet) < radius) {
doStuff();
}
if (((ObjMove_GetX(player) - ObjMove_GetX(bullet))^2 + (ObjMove_GetY(player) - ObjMove_GetY(bullet))^2 )^0.5 < radius) {
doStuff();
}
case(EV_REQUEST_IS_DURABLE_SPELL) {
SetScriptResult(true);
}
case(EV_TIMEOUT) {
if(!ObjEnemyBossScene_GetInfo(GetEnemyBossSceneObjectID,INFO_IS_DURABLE_SPELL)) {
// Show custom FAIL SPELLCARD etc.
}
}
How would I make it so that the boss starts with an idle animation, but when it moves, it switches to a moving animation which overrides the idle animation until it stops moving?
Another question, when I declare a variable (say, a bullet) in a loop{} (which is in a task), it seems to be local to the loop{} only, not public i.e I can't call it outside of the loop{} in the same task or outside of the task. Anyone know how to make them public? (At least to the task, but to the whole script would be cool.)
Is it possible to make the BGM persist between phases when you declared it within the first single script instead of the stage or plural script?
Hello. This is Nefer Nightbug, Shinto God of Insects here.I am not quite sure if this is a joke question or not. I'll answer them regardless:
I've had an idea sitting in the back of my head for, like, ages now.
My original intention was to do it in Blender, but, there's no way to aim bullets.
Is Danmakufu capable of handling...
- Circular combat, like in a circular arena?
- Actual stages, with fairies and things?
- Six stages, the Extra Stage, the Phantasm Stage, and one more stage?
- Stages without midbosses or bosses?
- Heavy amounts of Blender modeling and animation?
- Multiple hitpoints, but no lives (a bit like a cross between Legacy and Pointdevice Modes?)
Thank you.
Another 3D question: what is the standard method to render a long, endless path or hallway?There is no standard method, only preferred method. For simplicity with little to no 3D-elements you can use Texture UV scrolling. For more control + complexity you can use Z-position scrolling and resetting the pieces behind fog / vision.
Are there any ph3 player scripting tutorials out there? I can't find any and most player scripts I do find are for 0.12m. If there aren't, how would I go about learning how to make one myself?
Are there any ph3 player scripting tutorials out there? I can't find any and most player scripts I do find are for 0.12m. If there aren't, how would I go about learning how to make one myself?
I started with downloading one of gtbot's players (you can find it on bulletforge). Gtbot really wrote well-organized code that you can easily understand it. Then I started to make my own player by using gtbot's code as a template. xD
You can use this example (http://dmf.shrinemaiden.org/wiki/How_to_Write_Scripts#Player_Script).
Hi. The only way to deal with the Magic Circle that follows the boss (like, changing the sprite, deleting it, etc) is creating a custom system script and adding it in #System in the single/plural/etc?
Thanks!
Thanks for the answer. However, I don't know how to get rid of the default Magic Circle that comes with danmakufu (actually, the only way I found is modifying the default_system folder's files, but I don't think it is a good idea).
I also tried to copy-paste the default_system folder in my own script folder, modify the copied files, and call them in #system in my plural scrpit (I'm making only plural scripts so far). But it seems that they are ignored and it's used the default ones anyway.
Sorry if my explanation is a bit weird, English is not my first language.
#System["./default_system/Default_System.txt"]
then you can modify Default_System_MagicCircle.txt in the system folder that you copied. Hope this help xDif(Obj_IsVisible(objD2) == false){Obj_Delete(objD2);}
http://fat.gfycat.com/PaleDistantAxisdeer.webm
I was messing around with changing patterns into new ones, trying to get ideas for fun things I could do, but I noticed that bullets that fly off the screen are triggered and altered early (as you can see in the top of the screen), most of the pattern is transformed properly but the part that goes offscreen transforms instantly and doesn't home the player, but goes from one side of the screen to the other before being deleted instead.
I tried a whole bunch of things to counteract this but nothing seems to work. I tried having the task not trigger if the bullets disappear with thisCode: [Select]if(Obj_IsVisible(objD2) == false){Obj_Delete(objD2);}
But that didn't seem to do anything. Any suggestions? I altered the code so the circles would make a flower pattern with the homing butterflies in the end, but the missing piece at the top really messes it up visually. I really hope this is fixable.
Here's the pattern's code in case it's relevant.
http://puu.sh/l9tnh/c5911d58a9.txt
So, would verifying whether the object is deleted before spawning from its location be possible? Also, is it possible to work with offscreen bullets?
Use the archiver?I have installed some, but I had no imagination how there working '(mostly not working)
When using Danmakufu Archives (the executable is located in tools/FileArchiver.exe), you can safely archive your code. However, please note that your file paths must be EXACT (capitalization matters), and that directories can be a little funky without proper guidance.I completly forgot about that's Archiver :000
task slowBullet(graphic){
let obj = CreateShotA1(bossX, bossY, rand(2.5,4), rand(0,360), graphic, 0);
while(!Obj_IsDeleted(obj)){
// if bullet is within a distance of 55 to the player
if(((GetPlayerX() - ObjMove_GetX(obj))^2 + (GetPlayerY() - ObjMove_GetY(obj))^2)^0.5 < 55){
// slow down
}
yield;
}
}
1) How to read music/sounds/graphic that is in the .dat file? (When it was Archived by FileArchiver for ph3)
2) Which program/engine can run TouhouDanmakufu scripts too? (Please no 0.12m, ph3)
First one: Reference them as you would normally. If you had a file ScriptName/img/effect.png, and you archived it to img.dat, you should place img.dat inside ScriptName, but you do NOT need to change any of your paths. (i.e. GetCurrentScriptDirectory/img/effect.png is correct)
Just remember to give Danmakufu the archive path in your System script or something.
let r = GetShotDataInfoA1(ObjShot_GetImageID(obj),TARGET_ENEMY,INFO_COLLISION);
ObjShot_SetIntersectionEnable(obj,false);
let pl = GetPlayerObjectID;
while(!Obj_IsDeleted(obj)){
if(GetObjectDistance(pl,obj)<r&&ObjMove_GetSpeed(pl)>0){
let shot = CreateShotOA1(pl,0,0,2190,0);
ObjRender_SetAlpha(shot,0);
yield;
Obj_Delete(shot);
return;
}
yield;
}
I'm attempting to implement some bullets that only collide if the player is moving, and I've run into some trouble.
I can't figure out how to test if the player is currently moving.
The function "GetPlayerSpeed" returns the possible speeds of the player, not the current one
Using "ObjMove_GetSpeed" on the ID returned from "GetPlayerObjectID" always retturns 0 (I assume that the player object is not counted as a move Object?)
Is there a way to easily get the player's speed that I'm missing?
Is there another implementation of testing if the player is moving that I'm missing?
task bullet(){
let obj = // CreateShotBla();
while(!Obj_IsDeleted(obj)){
ObjShot_SetIntersectionEnable(obj, condition);
yield;
}
}
So if you want to check movement keys, you can use it as that condition.task bullet(){
let p = [ObjMove_GetX(player), ObjMove_GetY(player)];
let op = p;
let obj = // CreateShotBla();
while(!Obj_IsDeleted(obj)){
p = [ObjMove_GetX(player), ObjMove_GetY(player)];
ObjShot_SetIntersectionEnable(obj, (p != op));
op = p;
yield;
}
}
let state = ObjShot_Create(OBJ_SHOT);
function IsPlayerMoving(){ return Obj_GetValueD(state, "STATE_PLAYER_MOVING", false); }
task UpdatePlayerMoving(){
let player = GetPlayerObjectID();
let p = [ObjMove_GetX(player), ObjMove_GetY(player)];
let op = p;
while(!Obj_IsDeleted(state)){
p = [ObjMove_GetX(player), ObjMove_GetY(player)];
Obj_SetValue(state, "STATE_PLAYER_MOVING", (p != op));
op = p;
yield;
}
}
UpdatePlayerMoving();
task bullet(){
let obj = // CreateShotBla();
while(!Obj_IsDeleted(obj)){
ObjShot_SetIntersectionEnable(obj, IsPlayerMoving());
yield;
}
}
function Sound(path){
let obj = ObjSound_Create;
ObjSound_Load(obj,path);
ObjSound_SetSoundDivision(obj, SOUND_BGM);
ObjSound_SetRestartEnable(obj, true);
ObjSound_SetLoopEnable(obj, true);
ObjSound_SetLoopTime(obj, 0,300);
ObjSound_Play(obj);
ObjSound_SetVolumeRate(obj,95);
return obj;
}
instead of #bgm, but I'm open to switching to something else if that wold work better.@event{
case(game lags){
let lagAmount = Calculate Lag
Slow music(lagAmount)
}
}
I'm writing a script that is intended to be synced to the music and I was wondering if there was a way to have music that slows down if the game lags.There isn't.
Also, I have the music stopping if I pause, but it still plays when I click over to another window, even though that effectively pauses the rest of the script is there a way to fix that?Afaik, nope. Danmakufu behaviour as you have noticed. So far nobody has even tried to attempt something like this (making music lag / not continue when focussing the main window). The solution I guess is to play full screen (which you probably guessed yourself).
Thank you all, that's very helpful.No, it is a Move object, but essentially all players are going to be implemented by moving using SetPosition-like functions, rather than setting an angle and speed. GetAngle and GetSpeed will only return useful values if the objects have those attributes set to something. In the same way, if you create a Shot object without giving it an angle or speed and move it around with SetPosition, it won't return useful values for those functions either.
For clarity's sake, am I right in my guess that the player is not counted as a move object?
Why don't you just make sure the script doesn't lag anyway? (i.e: securing 60fps running)
How do I do this? is it code I need to include in my scripts/system or a vPatch type of thing; cause all my games still lag even with vpatch.vPatch? Why would you try to apply that for Danmakufu? What do you mean with all your games?
It made sense to me that vpatch would work on other stgs(e.g. danmakufu) apparently this is not the case, so forget about vpatch.That function simply changes the frame rate of Danmakufu, which is already 60 by default. It is not an anti-lag function, its intended purpose is to create a Youmu-esque sIowdown effect. It also cannot be used to speed the game up.
,
I found this function
StartSlow(TARGET_ALL, 60);
is this what I want to do? I tried it in @initialize and it changed some of the timing for the script, but the fps in the hud still fluctuated between 59.3 and 60.4. I tried slowing it to 40 which worked but "slowing" it to 70 did not make it go any faster. Is this the intended function to secure 60fps, I am quite inept when it comes to danmakufu.
but the fps in the hud still fluctuated between 59.3 and 60.4.However, this is not really a significant source of lag. I've observed Danmakufu keeping these fluctuations (on the main menu at least) even under the most ideal of conditions. If small fluctuations like this are all you're experiencing, then syncing music to Danmaku shouldn't be an issue when it comes to the framerate.
If it ends up lower than that anyway, then either your scripts need to be better optimized or your computer hardware (specifically the CPU) needs to be upgraded. Do you have a ton of objects running tasks all at once? Are you deleting objects after you are finished with them? Are you using too many curvy lasers? Those in particular are WAY more process intensive than the ones that ZUN himself uses. Do you have an abundance of visual effects, possibly with primitive objects using large numbers of vertices? Are you making Danmakufu do an excessive amount of trig calculations (i.e. once every frame)?
There are quite a few things you can do to reduce lag in your scripts, many more than I'm capable of thinking of at the moment. Maybe it would help to make a more comprehensive list of things that can bog Danmakufu's framerate down.
However, this is not really a significant source of lag. I've observed Danmakufu keeping these fluctuations (on the main menu at least) even under the most ideal of conditions. If small fluctuations like this are all you're experiencing, then syncing music to Danmaku shouldn't be an issue when it comes to the framerate.
task lagMusic{
lagMemory += 60-GetCurrentFps();
if(lagMemory>60){
ObjSound_Stop(bgm);
wait(1);
ObjSound_Play(bgm);
lagMemory -= 60;
}
}
but wanted to see if anyone had a more elegant solution. I also wanted a way to skip ahead if the framerate speeds up like it does when you hold ctrl, but I couldn't find a speed up music function. Why don't you just make sure the script doesn't lag anyway? (i.e: securing 60fps running)made it seem like there was a trivial way to force a framerate, if there is i would like to use it instead of a hack
99% sure it's my my comp: 4 tasks, no lasers curvy or otherwise, black background, I don't even have many bullets yet just moving and animating the boss. I do use a lot of trig so that might be it.It would have to be a heck of a lot to cause any sort of slowdown with that barebones of a script.
I find it a little surprising that no one has ever needed synchronized music beforeThat isn't the case, there just usually isn't a situation where your computer performs poorly enough that this is a concern.
Synchronized BGM discussion on last pageOkay I just implemented this myself out of interest. Works pretty decently. Would appreciate testers.
Hi! How can I make a bullet with a "curved" fall? Something like a parabola. Like in a free fall.The CreateShotB series uses x-speed and y-speed parameters rather than speed and angle. In particular, CreateShotB2's usage is:
CreateShotB2(x, y, x_speed, y_speed, x_accel, y_accel, x_max_speed, y_max_speed, graphic, delay)
By having any initial x/y-speeds and a positive y-acceleration you will get a gravity-like effect. ObjMove_AddPatternB2(obj, frame, x_speed, y_speed, x_accel, y_accel, x_max_speed, y_max_speed)
Your code seems like it could work with some modifications, if GetCurrentFps worked the way you wanted it to. The way you've written it, it'll only pause for one frame (theoretically) after accumulating 60 frames-worth of lag. If you wanted to wait for one frame when one frame is lost, you'd have to check (lagMemory >= 1) and subtract 1. You'd probably also want to center the timing around +/- 0 frames, so (lagMemory >= 0.5) and subtracting 1 would be better.
task lagMusic{
lagMemory += 60-GetCurrentFps();
if(lagMemory>=1){
ObjSound_Stop(bgm);
wait(1);
ObjSound_Play(bgm);
lagMemory -= 1;
}
}
would see 59 fps for 1 frame then skip the next frame, meaning that a script running at 59fps would have music running at half speed. In my original (which is still a naive approach) would run at 59fps for 60 frames before skipping one so 61 frames of music for 60 frames of gameplay. The difference in the actual fps and the expected fps per frame is only worth 1/60 of a frame which is why I waited to get 60 of them before skipping one. Either way, this method wasn't really fleshed out, just my first blush idea.(It is less accurate the farther from 60fps your script goes now that I think more of it) Hi! How can I make a bullet with a "curved" fall? Something like a parabola. Like in a free fall.
Something like this: http://puu.sh/lta27/98a497a6a6.png
More general: http://puu.sh/lta0c/c89e578c7c.png
Thanks!
Thanks to both, that's exactly what I was looking for :D
Btw, there is a guide or some script that I can use to learn how to put dialogues?
CreatePlayerSpriteObject() just change the texture or source rects to show difference faces
CreateBossSpriteObject() same as the player
CreateDialogueBox() best to just have one of these unless you want the GFW - Present style floating dialogue boxes
CreateTextObject() for whoever is talking, again only one is needed, just change the text for whoever is talking
blahblahblah talking...
CleanUp everything else afterwards, deleting the previously created objects, removing textures, etc...
I can't really come up with an example code right now but that's sort of a quick step by step guide to how it could work for something extremely simple. The functions I mentioned don't actually exist but you'll be using ObjSprite_Create(OBJ_SPRITE_2D); for the player, boss, and text background, and finally ObjText_Create() for the actual dialogue text. I suggest looking at the official danmakufu documentation for ph3 (Google Translate does well enough here), the danmakufu wiki we have is also applicable but I always recommend using the official documentation because it contains more information about the engine and is more accurate atm.
<code> would see 59 fps for 1 frame then skip the next frame, meaning that a script running at 59fps would have music running at half speed. In my original (which is still a naive approach) would run at 59fps for 60 frames before skipping one so 61 frames of music for 60 frames of gameplay. The difference in the actual fps and the expected fps per frame is only worth 1/60 of a frame which is why I waited to get 60 of them before skipping one.Beep boop, I was mistaken, yes. I didn't scale it in my head properly and figured "FPS is a measure of frames so a difference of 1 means 1 frame".
Ah,Hello there everyone :derp:
I know it's kinda silly question
BUUUTT :V
I was wondering how to spawn bullets on the laser?Like on the end of the laser and stuff? ???
You know the starting point, angle, and length of the lasers. Knowing that, you can use trigonometry to place bullets along the length of the laser.
That's the problem
I don't understand trigonometry
What are you doing here? Get your butt out of your chair and go to school for once.
Anyway, I'd suggest learning basic trigonometry. There are many resources on the Internet that they're not worth linking from here.
There isn't a guide for dialogue scenes but it is very simple to make. Stealing code from others isn't always a good choice either, especially if you don't get permission to use their code.
The general idea is that you need: one sprite object for the player's cutin, another for the boss, a background sprite object for the text background, and finally a text object. so you can just setup a system that works like this.
#include"./FuncList.dnh"
@Initialize{
RenderBG;
}
task RenderBG {
let obj = ObjPrim_Create(OBJ_SPRITE_2D);
let imgpath = currdir~"./img/cielo2.png";
let alpha = 150;
let scale = 0.8;
ObjPrim_SetTexture(obj, imgpath);
ObjSprite2D_SetSourceRect(obj, 0, 0, 512, 1024);
ObjSprite2D_SetDestCenter(obj);
ObjRender_SetPosition(obj, CenterX, CenterY, 0);
ObjRender_SetAlpha(obj, alpha);
Obj_SetRenderPriority(obj, 0.21);
ObjRender_SetScaleXYZ(obj, scale, scale, 1);
moverBG(obj);
}
task moverBG(obj){
let x = 0;
let y = 0;
while(!Obj_IsDeleted(obj)){
ObjRender_SetPosition(obj, x, y, 0);
x++;
y++;
yield;
}
}
But if I call this file with #Background in the plural script, the image doesn't move at all. However, if I put the task "RenderBG" in the @Initialize of the plural script, it works (obviously deleting the @Initialize in the BG script).
Why does this happen? Thanks.
Thank you Sparen, it worked :D
Btw, there is no default item script?
Good day, everyone.
Who had wrote often STGs?
Which fps-problem can I face during writing STGs? What should I beware? My big problem is that Boss Fight in Stage runs in low fps (Even if I upload it from the beginning of the Stage). But when I play just Plural, all work successfully. Somebody knows that trick?
if (x && y) {} //if x is false, then y won't even be evaluated
-Kill all tasks when they are completedWays to improve your FPS:
-Short circuit your boolean expressions:Code: [Select]if (x && y) {} //if x is false, then y won't even be evaluated
-Remove unused variables and redundant statements
-etc.
One more question..
For what is this " .def " file?
Which programm language used there? What can I add there more?
Where I can learn more about this file (language)?
// Path to the package script
package.script.main = script/ExRumia/ExRumia_Package_Main.txt
// Window title
window.title = test
// Screen dimensions
screen.width=1024
screen.height=576
It is a configuration file.Code: [Select]// Path to the package script
package.script.main = script/ExRumia/ExRumia_Package_Main.txt
// Window title
window.title = test
// Screen dimensions
screen.width=1024
screen.height=576
Yes, that I know already. But if there something more than that? Where can I see more information about this configuration file?
Sorry please..
How do I point CreateStraightLaserA1 angle, to object, that moves with ObjMove_SetAngularVelocity.
When I make this, lasers angle points to object askew.
What are you trying to do? Are you trying to move the base of the laser depending on the location of a bullet or are you aiming the laser at a specific place? You need to state your intention more clearly.Sorry my English.
Sorry my English.
Aiming lasers to Shot object that moving in angular velocity.
You can't use ObjMove_SetAngularVelocity for that. You need to use a task.
task Lantern{
…
ascent(ang in 0..20){
let obj = CreateShotA1( … );
Laser(obj);
}
task Laser(object){
ObjMove_SetAngularVelocity(object, 0.5);
let laser = CreateStraightLaserA1( … );
while(!Obj_IsDeleted(object)){
ObjStLaser_SetAngle(laser, ObjMove_GetAngle(object));
yield;
}}
…
Approximately I had thisCode: [Select]task Lantern{
?
ascent(ang in 0..20){
let obj = CreateShotA1( ? );
Laser(obj);
}
task Laser(object){
ObjMove_SetAngularVelocity(object, 0.5);
let laser = CreateStraightLaserA1( ? );
while(!Obj_IsDeleted(object)){
ObjStLaser_SetAngle(laser, ObjMove_GetAngle(object));
yield;
}}
?
task Laser(object){
let laser = CreateStraightLaserA1( ? );
while(!Obj_IsDeleted(object)){
ObjStLaser_SetAngle(laser, ObjMove_GetAngle(object) + 0.5);
yield;
}
}
Change it toCode: [Select]task Laser(object){
let laser = CreateStraightLaserA1( ? );
while(!Obj_IsDeleted(object)){
ObjStLaser_SetAngle(laser, ObjMove_GetAngle(object) + 0.5);
yield;
}
}
if(sdt*60 > skip_param/2){
sdt -= skip_param/60;
ObjSound_Stop(bgm);
c = 0;
}
Good day.
How can I forbid 'backskape' key in Package script?
I want forbid players to retry game with this key method. Only: -> Esc -> Retry.
As long as you don't explicitly program this functionality in, pressing backspace shouldn't retry the stage.Pressing "Backspace", stage will always start from the beginning (like a retry)
Pressing "Backspace", stage will always start from the beginning (like a retry)
if(!IsReplay() && GetKeyState(KEY_BACK) == KEY_PUSH){
TerminateStageScene();
TStageScene("");
return;
}
Where can I find documentation on how to change the magic circle graphic or remove it altogether? I can't seem to find it anywhere. Thanks in advance.
Ahh, I see. Thanks! Also, is there a way to rotate a primitive object around its axis? I made a pentagram for my boss that flickers, "breathes" and wobbles behind her slightly, but it looks kind of dull without the pentagram itself rotating as well. ObjMove doesn't seem to work on it. Would I have to register it as some type of object to be able to apply rotation to it? Since ObjRender_SetAngle doesn't really do that, it just spins it in a 3D-ish sort of way.
Thanks again!
You need to center it at (0, 0, 0) and use ObjMove_SetPosition and ObjMove_SetAngleZ.
Ahh, I see. Thanks! Also, is there a way to rotate a primitive object around its axis? I made a pentagram for my boss that flickers, "breathes" and wobbles behind her slightly, but it looks kind of dull without the pentagram itself rotating as well. ObjMove doesn't seem to work on it. Would I have to register it as some type of object to be able to apply rotation to it? Since ObjRender_SetAngle doesn't really do that, it just spins it in a 3D-ish sort of way.
Thanks again!
Fluffy. You can't use ObjMove functions on primitive objects.
task Penta{ // Pentagram to surround her that rotates
let objPen = ObjPrim_Create(OBJ_SPRITE_2D);
let scale = 0.7;
let angle = 180;
let switch = 0.001;
ObjPrim_SetTexture(objPen, cDir ~ "sprite/fx/penta.png");
ObjSprite2D_SetSourceRect(objPen, 0, 0, 256, 256);
ObjSprite2D_SetDestCenter(objPen);
ObjRender_SetBlendType(objPen, BLEND_ALPHA);
Obj_SetRenderPriorityI(objPen, 21);
ObjMove_SetAngularVelocity(objPen, 2);
while(BossLife > 0){
ObjRender_SetPosition(objPen, BossX, BossY, 0);
ObjRender_SetAlpha(objPen, rand_int(155, 255)); // Flickering
ObjRender_SetScaleXYZ(objPen, scale, scale, scale); // Breathing
ObjRender_SetAngleX(objPen, 40 * cos(angle)); // Wobbling/rotating
ObjRender_SetAngleY(objPen, 40 * sin(angle));
angle += 0.5;
scale += switch;
if(scale >= 0.8 || scale <= 0.7){switch *= -1;}
yield;
}
}
I expected the answer to be something simple but damn ;_;. That worked perfectly, thanks again!
Hi! I'm a newbie of Danmakufu and this is my first post. Also due to my age, I haven't much knowledge of trigonometry and stuff like that.
So, I have a question: how do apply gravity to a bullet? I mean, if I shoot a bullet upward, how can I make it go downward.
Like in the Suwako's spell "Froggy Braves the Elements"
Sorry my English by the way-
Is there any method to unpack dat. files, that were archived by FileArchiver for ph3.
I lost my original scripts.
Here I am again-
I've got another question: how do I switch the HUD to "fullscreen" in a script?
Like this https://youtu.be/t9ICLqUh5vA?t=192 (https://youtu.be/t9ICLqUh5vA?t=192)
Is there any place that talks about how to spawn star patterns like Sanae's? I've been looking all over but can't find any. I tried looking at Ultima's MoF script but it kept crashing so I assume it's probably due to the version of the script being too old or something.
I do have an idea of how to spawn them but I'm worried it might be overly complicated. Is there any simple way to spawn them, and if so, could anyone share that?
Thanks!
Here I am again-
I've got another question: how do I switch the HUD to "fullscreen" in a script?
Like this https://youtu.be/t9ICLqUh5vA?t=192 (https://youtu.be/t9ICLqUh5vA?t=192)
Disregarding what sparen said this is pretty simple to do, yes it does require you to modify the default system script (make sure to include this in your script when uploading it for others to play), but the task itself isn't particularly difficult at all for anyone.
You mainly just want to remove all of the HUD and use the SetStgFrame(left,top,right,bottom,min pri, max pri); the min and max priority arguments are 20 and 80 by default. For fullscreen you can use SetStgFrame(0,0,640,480,20,80);, to get the original screen back you use SetStgFrame(32,16,416,464,20,80);. The rest is just removing the HUD elements which are found within the system script, the default system script is located in script/default_system/ folder.
You can use X-Ripper, but it unpacks them with generic names like "file000, file001", etc.Good program, but it unpacks only graphics, audio and video. Ok. But I have .txt files too. How to unpack them?
tween two points? Like, let's say I have two enemies standing diagonal from each other across the screen, is it possible to spawn a line of bullets between them? Thanks!
ascent (i in 0..numbullets) {
//CreateShot at Enemy1X + i*(totaldistance/numbullets - 1)*cos(angle), Enemy1Y + i*(totaldistance/numbullets - 1)*sin(angle)
}
Ahh, I see. Is there a function for getting the distance between two objects or would I have to make one manually? I vaguely recall reading about something like that in the documentation but I can't seem to find it right now.
function bulletLine(x1, y1, x2, y2, n){
let dx = (x2 - x1) / (n - 1);
let dy = (y2 - y1) / (n - 1);
ascent(i in 0..n){
bullet(x1 + i*dx, y1+ i*dy);
}
}
task TxtExtractor(filepath)
{
let objF = ObjFile_Create(OBJ_FILE_TEXT); // create a text file stream object
ObjFile_Open(objF,filepath); // open the file (not entirely sure if this part will work on archive files but worth a try)
ObjFile_Store(objF); // store the file again, since dnh itself cannot write to files it should make a copy on the HDD
Obj_Delete(objF); // cleanup
}
There is no way to get them back, and no one has made an archive dumper for ph3. Never delete your backups and always keep backups for this exact reason.
You could probably do some trick with ObjFile objects and reprint the text from the files in the archive assuming you know the name of them.Code: [Select]task TxtExtractor(filepath)
{
let objF = ObjFile_Create(OBJ_FILE_TEXT); // create a text file stream object
ObjFile_Open(objF,filepath); // open the file (not entirely sure if this part will work on archive files but worth a try)
ObjFile_Store(objF); // store the file again, since dnh itself cannot write to files it should make a copy on the HDD
Obj_Delete(objF); // cleanup
}
Tell me if it works since I don't have time to try it myself. If it doesn't then the data will be permanently stored in the archive.
and no one has made an archive dumper for ph3.
Unfortunately, it doesn't work. If using <ObjFile_OpenNW>* then it saves empty file, but of course with the same name.
Also thanks a lot for helping!
Edit:Danmkufu ph3 engine could see this .txt files in .dat files
That was written for 12m, not ph3.
Using NW will create a file if one doesn't exist. Before making sure you did this correctly, did you test the function after using the AddArchiveFile() feature? If so, then you are out of luck.
How can I create bullets that are constantly aimed at you? Like in "Fantasy Seal", so to say.
task BulletCommandsA1(obj) {
while (!Obj_IsDeleted(obj) && ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 0) {
ObjMove_SetAngle(obj, GetAngleToPlayer(obj));
yield;
}
}
Pass the bullet ID as a parameter to a task. In that task, have a statement where, while the bullet has not been deleted and the boss is not dead (if applicable), the bullet sets its angle to GetAngleToPlayer(bullet) every x frames. Make sure to yield in @MainLoop as well as in the while loop.
Ex:Code: [Select]task BulletCommandsA1(obj) {
while (!Obj_IsDeleted(obj) && ObjEnemy_GetInfo(objBoss, INFO_LIFE) > 0) {
ObjMove_SetAngle(obj, GetAngleToPlayer(obj));
yield;
}
}
And if I want the bullet to stop following the player after like 60 frames, what do I do?
CreateShotA1(x+R1*cos(a), y+R2*sin(a), speed, angle, graphic, delay;
R1 = r*cos(n);
R2 = r*sin(n);
n++;
Were "r" is the max distance from the center of spawn.Hi!Depends a bit what context this is and what you're trying to accomplish. If this is intended to be part of a player, you can use an item script to be able to gain access to the EV_DELETE_SHOT events and have fairly good control over the shots you delete. Depending on how you're deleting them you might have an easier method as well.
I want to get the X and Y (orat least the ID?) coordinate of any enemy shot deleted by a player shot. But I have no idea how I can do this...
Someone have a simple idea to do this? Or a miracle function I miss?
I'm wondering why after I running "th_dnh" in th_dnh_ph3So, you can't control the characters or even navigate the menus? That sounds strange. Even though you didn't change the config, can you check what config.exe shows in the Key section?
My keyboard somehow won't work, even though I update with the latest version of ph3
And I didn't make any single changes with the config
I still can press Alt F4 to quit from it though...
Besides running "th_dnh", I still can type normally without problems...
Hello there!
I'm really bad at math,but was wondering how to make :
An oval of bullets(I mean their spawn form is oval) rotaiting clockwise
I mean..uhm..like this http://cs631629.vk.me/v631629252/5963/MDqfxQ15VHY.jpg
so bullet's spawn position is 'rotating' clockwise
I hope you understand u-u
// x0 : origin x-coordinate
// y0 : origin y-coordinate
// width, height : size of ellipse
// u : angle of ellipse
// num : number of bullets
ascent(t in 0..360/num){
let x = x0 + width*cos(t*num)*cos(u) - height*sin(t*num)*sin(u);
let y = y0 + width*cos(t*num)*sin(u) + height*sin(t*num)*cos(u);
CreateShotA1(x, y, s, t*num + u, g, d); // s, g, d are same as usual
}
So, you can't control the characters or even navigate the menus? That sounds strange. Even though you didn't change the config, can you check what config.exe shows in the Key section?Not like I can change it neither know how to change it though...
highlight the input you want to change and press a key on your keyboard or a button on your controller to change itI tried it along with several random tries but nothing is changed
Thank you! x3
Lefkada: Not quite, the math is a bit more complicated and involves rotation matrices :)Code: [Select]// x0 : origin x-coordinate
// y0 : origin y-coordinate
// width, height : size of ellipse
// u : angle of ellipse
// num : number of bullets
ascent(t in 0..360/num){
let x = x0 + width*cos(t*num)*cos(u) - height*sin(t*num)*sin(u);
let y = y0 + width*cos(t*num)*sin(u) + height*sin(t*num)*cos(u);
CreateShotA1(x, y, s, t*num + u, g, d); // s, g, d are same as usual
}
So what you'll want to do with this is set up the ellipse like you want, then loop this while incrementing u each time to rotate the ellipse.
Does somebody know how to divide lifes/bombs in pieces. Like in last TouhouGames. When you collect 3 life-pieces, You will get one life. I hope somebody understands me :V
Depends a bit what context this is and what you're trying to accomplish. If this is intended to be part of a player, you can use an item script to be able to gain access to the EV_DELETE_SHOT events and have fairly good control over the shots you delete. Depending on how you're deleting them you might have an easier method as well.I want to make a spell bullet that delete Enemy Shots and spawn Player Shot at their positions. I just use the ObjShot_SetEraseShot to delete enemy shots.
It is also possible to give fractions of a life, but I don't recommend this method because of precision errors.
I had mkm fix this in pre6 (not pre6a) before then the live and bomb values in replays would be saved as 32bit integers, now they save as floats. (assuming since that's what everything else uses)
task DoSomething(x,y)
{
loop
{
CreateShotA1(x,y, ...);
yield;
}
}
You can use a boss object for the main boss and enemy objetcs for the other bosses ;). It works almost the same way.
And how do I make enemies that share 1 lifebar?
ObjEnemy_SetIntersectionCircleToShot(objBoss, ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 32);
ObjEnemy_SetIntersectionCircleToPlayer(objBoss, ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 24);
ObjEnemy_SetIntersectionCircleToShot(objBoss, ObjMove_GetX(objEnemy), ObjMove_GetY(objEnemy), 32);
ObjEnemy_SetIntersectionCircleToPlayer(objBoss, ObjMove_GetX(objEnemy), ObjMove_GetY(objEnemy), 24);
The quick and dirty way is to place a hitbox on the non-boss enemies while directing the damage to the boss.
Ex:Code: [Select]ObjEnemy_SetIntersectionCircleToShot(objBoss, ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 32);
ObjEnemy_SetIntersectionCircleToPlayer(objBoss, ObjMove_GetX(objBoss), ObjMove_GetY(objBoss), 24);
ObjEnemy_SetIntersectionCircleToShot(objBoss, ObjMove_GetX(objEnemy), ObjMove_GetY(objEnemy), 32);
ObjEnemy_SetIntersectionCircleToPlayer(objBoss, ObjMove_GetX(objEnemy), ObjMove_GetY(objEnemy), 24);
if(ObjEnemy_GetInfo(objEnemy, INFO_LIFE) < x)
You should already have it in your script to check if the boss isn't dead yet.
Hi.Well sometimes people create their own by using Object Lasers and build it off from there , or another option is a trail of (ADD) bullets instead which is much harder and could potentially lag, it's just a matter of imagination i guess
I see some peoples using their own curved lasers instead of default laggy&shitty curved lasers. But I don't really understand how it works and how I can do this. Someone have some ideas and can help me? I already watch into custom lasers scripts but It's hard to understand with almost no informations and help.
Hi all againWrong function and code. You need EV_REQUEST_TIME see here:
I wonder how should I change the timer from 80 to 40 for ex.
ObjEnemyBossScene_SetSpellTimer is not working :u
@Event {
alternative(GetEventType())
case(EV_REQUEST_LIFE) {
SetScriptResult(x);
}
case(EV_REQUEST_TIMER) {
SetScriptResult(y);
}
case(EV_REQUEST_SPELL_SCORE) {
SetScriptResult(z);
}
}
Wrong function and code. You need EV_REQUEST_TIME see here:Code: [Select]@Event {
alternative(GetEventType())
case(EV_REQUEST_LIFE) {
SetScriptResult(x);
}
case(EV_REQUEST_TIMER) {
SetScriptResult(y);
}
case(EV_REQUEST_SPELL_SCORE) {
SetScriptResult(z);
}
}
I was quite surprised with this question, it is basic stuff actually.
((9Well, you didn't exactly say that in your original post.
I know thisss
I mean I need to change the timer WHILE spellcard is active
like,suddenly change the timer
Well, you didn't exactly say that in your original post.
I don't think you can even freeze / re-edit the timer.
Instead of using the real timer, why not just avoid setting the default timer ? It will default to infinite time remaining, and you can then use your own custom timer with multiple variables. You will have to set a "spellcard get" score manually however.
Well sometimes people create their own by using Object Lasers and build it off from there , or another option is a trail of (ADD) bullets instead which is much harder and could potentially lag, it's just a matter of imagination i guessI see almost how to do with bullets but with Object Lasers? How can I do this (without using actual CreateCurveLaserA1)?
I see almost how to do with bullets but with Object Lasers? How can I do this (without using actual CreateCurveLaserA1)?Doing it with lasers , is just the same as trailing bullets but the "tip" is a small object curvy laser that leaves more lasers making it seems like a curvy laser but its actually just trailing, you can make the tip and the trail as an object if you really dont want to use default functions
Okay. I never thought I can use lasers (loose lasers i guess?). But it don't cause more fps drops with long lasers than with bullet trail?A laser leaving a trail of lasers that are like 10 in length Shouldn't cause fps drops , just try to make sure those trails get deleted afterwards
Danmakufu has that feature built in. Use SetStageIndex() and load the correct stage. The Score, Graze, etc... is already recorded per stage
task bullet1{
let obj1=.....
stuff;
}
task bullet2{
let obj2=.....
stuff;
}
function ObjectA(){
let objA = ObjSomething_Create();
// initialize objA
task DoStuffA(objA){
while(!Obj_IsDeleted(objA)){
// running object behaviour
yield;
}
}
DoStuffA(objA);
return objA;
}
function ObjectB(){
let objB = ObjSomething_Create();
// initialize objB
task DoStuffB(objB){
while(!Obj_IsDeleted(objB)){
// running object behaviour
yield;
}
}
DoStuffB(objB);
return objB;
}
let objA1 = ObjectA(); // makes an A object and puts its object ID into this variable
let objB1 = ObjectB(); // makes a B object and puts its object ID into this variable
// do things with both objA1 and objB1
let listA = [];
let listB = [];
loop(m){
listA = listA ~ [ObjectA()];
}
loop(n){
listB = listB ~ [ObjectB()];
}
Well, check the line before that wait(120) again. It's line 19.
In the future, these sorts of one-off questions generally go in the stickied ph3 Q&A threads (https://www.shrinemaiden.org/forum/index.php/topic,16584.0.html).
A laser leaving a trail of lasers that are like 10 in length Shouldn't cause fps drops , just try to make sure those trails get deleted afterwardsYou use LooseLasers or StraightLasers to make the trail?
#Player["player1_path", "player2_path", "etc"].
Juste use a , between every path ;).
#ID[YourScriptIDHere]
in the header, and know if I can use it to trigger certain events in stage,like:if(GetOwnScriptID()=="MIDBOSS"){ stuff;}
Hello, i'd like to know how to useCode: [Select]#ID[YourScriptIDHere]
in the header, and know if I can use it to trigger certain events in stage,like:Code: [Select]if(GetOwnScriptID()=="MIDBOSS"){ stuff;}
I've been trying to do so, but without success.Can somebody help?
hello im pretty fresh here :V
I tried figuring this out for such a long time, to no avail: How do I make bullets spawn in a circle (or any other pattern) continuously, similarly to this (https://www.youtube.com/watch?v=_j-yefQtzmA)?
Thisdefinitelyprobably is a noob question, but that's because I'm quite new to Danmakufu.
loop(5){
CreateShotA1(ObjMove_GetX(objBoss) + 60*cos(angleT), ObjMove_GetY(objBoss) + 60*sin(angleT), 1, angleT, 1, 0);
angleT += 360/5;
}
If you want a pattern to fire continuously, use a while loop where the while condition is whether or not the boss has more than 0 HP. Make sure you have at least one yield; in the while loop, and a yield in @MainLoop.
As for the circle, use standard trigonometry to fire the bullets. For example, if I want a circle with 5 bullets in it and a radius of 60, I would doCode: [Select]loop(5){
CreateShotA1(ObjMove_GetX(objBoss) + 60*cos(angleT), ObjMove_GetY(objBoss) + 60*sin(angleT), 1, angleT, 1, 0);
angleT += 360/5;
}
where angleT is the starting angle to fire at.
CreateShotA1(x, y, 3, 60, 1, 10) //x and y are values increasing or decreasing every frame, depending on the timing
loop(36) {
CreateShotA1(x+r*cos(dir),y+r*sin(dir),v,dir,type,delay);
dir+=360/36;
}
loop(36) {
CreateShotA1(x+r*cos(dir),y+r*sin(dir),v,dir,type,delay);
dir+=360/36;
yield; // Added a yield for 1-frame delay
}
I typed only variables because you decide the rest. r = radius.Tried it out, and it's not really what I'm looking for...And that is exactly achieved with delaying the loop for spawning such a circle per frame.
See how the places where the bullets spawn kind of circle around Patchouli, instead of creating one,
Tried it out, and it's not really what I'm looking for...
Referring to Satellite Himawari again. See how the places where the bullets spawn kind of circle around Patchouli, instead of creating one, singular ring at the same time? That's what I'm looking for.
Sorry if I'm being bothersome, I just can't get this to work at all...
while(!Obj_IsDeleted(objBoss){
loop(2){
CreateShotA1(ObjMove_GetX(objBoss) + 60*cos(angleT), ObjMove_GetY(objBoss) + 60*sin(angleT), 1, angleT, 1, 0);
angleT += 360/2;
}
angleT+=2.6; //angle to increment each time. Should not divide into 360
wait(2);
}
Well, I didn't want to give you the entire thing, but w/eCode: [Select]while(!Obj_IsDeleted(objBoss){
loop(2){
CreateShotA1(ObjMove_GetX(objBoss) + 60*cos(angleT), ObjMove_GetY(objBoss) + 60*sin(angleT), 1, angleT, 1, 0);
angleT += 360/2;
}
angleT+=2.6; //angle to increment each time. Should not divide into 360
wait(2);
}
I've been looking through Danmakufu's default system functions and messing with them, and I've hit a problem.
Where do I tell a script to use a different pause script to the default?
Is a specific kind of script needed? (e.g. stage/package)
Help please.See my post last page:
How should I connect two objects (for example: GetObjectDistance( obj1, obj2 ); when both of objects are in different loops?
See my post last page:
https://www.shrinemaiden.org/forum/index.php/topic,16584.msg1230565.html#msg1230565
The answer is essentially, define the variables that store the object IDs in a scope accessible by both loops. If your loops create your objects and assign it some behavior, do like I write in that post where you wrap the "behavior" task in a function that returns the new object.
Again, the level of detail changes depending on your actual problem. How many objects? Are they created and deleted often?
function ObjectA(){
ascent( i in 0..10){ // for example creating rings, but naturally this will wrong, because id will not return
let objA = ObjSomething_Create();
}
// initialize objA
task DoStuffA(objA){
while(!Obj_IsDeleted(objA)){
// running object behaviour
yield;
}
}
DoStuffA(objA);
return objA;
}
that's why I made than thistask TShot{
ascent(i in 0..10){
let obj = ObjectA(); //Creating rings, but id is again in the loop.
}
}
Is it possible to get this id out or something like that?
function ObjectA(){
let objA = ObjSomething_Create();
// initialize objA
task DoStuffA(objA){
while(!Obj_IsDeleted(objA)){
// running object behaviour
yield;
}
}
DoStuffA(objA);
return objA;
}
and then, if the tasktask TShot{
ascent(i in 0..10){
ascent(j in 0..10){
let obj = ObjectA(); //Creating rings, but id is again in the loop.
}
}
}
You do the function's ascent with ascent (i in 0..10) and then, the task's ascent with ascent (j in 0..10).
Maybe I'm wrong but if I understand, in your function you create a ring of 10 bullets and then, in the task, you repeat 10 time the same ring of bullets?
If you want just a ring of bullet, you don't need one of the two ascent I think. Of maybe I just don't understand what you want to do...